C++语言下的windows网络编程(SOCKET)
本文的主要目的是以C++语言在windows下实现UDP网络服务端的代码(VS2022)。主要内容为讨论并实践windows下的socket网络编程。
初始化的大部分内容与之前的一篇博客代码相同:https://blog.csdn.net/Blanchet/article/details/129113568。
头文件一览
#include<iostream>
#include<WinSock2.h>
#include<WS2tcpip.h>
#include<stdlib.h>
#pragma comment(lib,"ws2_32.lib")
建立SOCKET并初始化
//初始化WSA
WSADATA wsaDATA;
WORD wVersion = MAKEWORD(2, 2);
if (WSAStartup(wVersion, &wsaDATA) != 0)
{
printf("WSAS errocode is %d\n", WSAGetLastError());
return -1;
}
//初始化SOCKET
int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("socket err is \n");
return -1;
}
建立UDP数据变量结构体并初始化主机IP地址
//MSG_t接受消息结构体
typedef struct msg_t
{
char type;
char text[100];
} MSG_t;
//IP地址和端口定义
sockaddr_in ServerAddr;
ServerAddr.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.1.1", &ServerAddr.sin_addr);
ServerAddr.sin_port = htons(1234);
//定义消息体
MSG_t msg = {0};
msg.type = 1;
int i = 0;
for (i = 0; i <= 98; i++)msg.text[i] = i;
msg.text[99] = ' \0';
send()
介绍一下sendto函数:
int WSAAPI sendto(
[in] SOCKET s,
[in] const char *buf,
[in] int len,
[in] int flags,
[in] const sockaddr *to,
[in] int tolen
);
详情可看文档:https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto。
变量1:SOCKET主机。
变量2:发送消息的char指针。
变量3:发送消息的长度。
变量4:一些特殊操作的旗帜,若无则是0。
变量5:发送的目的地地址IP。
变量6:目的地地址IP长度。
返回值,正常发送会返回发送的数组的字节数,否则会返回SOCKET_ERROR 值。
范例如下:
//发送消息体
for (i = 0; i <= 4; i++)
{
printf("UDP Send Start!\n");
if (sendto(sockfd, (char*)&msg, sizeof(msg), 0, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
perror("sendto system err is");
printf("WSA sendto errocod is %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
printf("UDP Send End!\n");
}
最后加入关闭SOCKET的代码就行了。
成果展示与代码
注意:这里有一个笔者没搞定的BUG。一般情况下不要使用bind函数绑定客户端,否则会出现UDP数据发送不出去的BUG。具体原因是socket套接字结构的设置方式不是这么弄的,下篇文章继续讲socket结构。(不要用bind和客户端相连,会处bug的)

#include<iostream>
#include<WinSock2.h>
#include<WS2tcpip.h>
#include<stdlib.h>
#include"UDPVar.h"
#pragma comment(lib,"ws2_32.lib")
typedef struct msg_t
{
char type;
char text[100];
} MSG_t;
int main() {
printf("UDP Start!\n");
//初始化WSA
WSADATA wsaDATA;
WORD wVersion = MAKEWORD(2, 2);
if (WSAStartup(wVersion, &wsaDATA) != 0)
{
printf("WSA errocode is %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
//初始化SOCKET
int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == INVALID_SOCKET)
{
perror("socket system err is \n");
printf("WSA SOCKET errocod is %d\n",WSAGetLastError());
WSACleanup();
return -1;
}
//IP地址和端口定义
//目的地IP
sockaddr_in ServerAddr;
ServerAddr.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.1.102", &ServerAddr.sin_addr);
ServerAddr.sin_port = htons(1234);
//定义消息体
MSG_t msg = {0};
msg.type = 1;
int i = 0;
for (i = 0; i <= 98; i++)msg.text[i] = i;
msg.text[99] = ' \0';
//发送消息体
for (i = 0; i <= 4; i++)
{
printf("UDP Send Start!\n");
if (sendto(sockfd, (char*)&msg, sizeof(msg), 0, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
perror("sendto system err is");
printf("WSA sendto errocod is %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
printf("UDP Send End!\n");
}
printf("UDP close\n");
closesocket(sockfd);
WSACleanup();
return 0;
}
本文介绍了如何使用C++在Windows环境下,通过VS2022进行UDP网络服务端的开发。主要涉及WSAStartup初始化、socket创建、IP地址设置、sendto函数用于数据发送等步骤。示例代码展示了发送UDP数据包的过程,同时指出不应在客户端使用bind函数,以免引发问题。
783

被折叠的 条评论
为什么被折叠?



