UDP server写法和TCP server差不多,区别就在于没有listen和accept,那我们来写写UDP吧
步骤
最开始,包含相应的头文件,引入网络库
第一步 初始化套接字
WORD wVersion;
WSADATA wsaData;
int err;
wVersion = MAKEWORD(2, 2);
err = WSAStartup(wVersion, &wsaData);
if (err != 0)
{
return err;
}
if (LOBYTE(wsaData.wVersion) != 2|| HIBYTE(wsaData.wVersion) != 2)
{
WSACleanup();
return -1;
}
注意,引入的winsock2的头文件,所以这里的wVersion版本都要改成2
第二步 创建套接字
SOCKET socksrv = socket(AF_INET, SOCK_DGRAM, 0);
if (INVALID_SOCKET == socksrv)
{
std::cout << "socket error=" << GetLastError() << std::endl;
return -1;
}
AF_INET(又称PF_INET)是 IPv4 网络协议的套接字类型,AF_INET6 则是 IPv6 的
选择AF_INET 的目的就是使用IPv4 进行通信
GetLastError是一个显示错误的函数
第三步 bind 地址和端口
SOCKADDR_IN addrsrv;
addrsrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrsrv.sin_family = AF_INET;
addrsrv.sin_port = htons(6001);
if (SOCKET_ERROR == bind(socksrv,
(SOCKADDR*)&addrsrv, sizeof(SOCKADDR_IN)))
{
std::cout << "bind error=" << GetLastError() << std::endl;
return -1;
}
第四步 等待接收数据
SOCKADDR_IN addrclie; /客户端套接字地址
int len = sizeof(addrclie);
char recvBuff[100]{};
char sendBuff[100]{};
while (1)
{
recvfrom(socksrv, recvBuff, 100, 0, (SOCKADDR*)&addrclie, &len);
std::cout << recvBuff << std::endl;
sprintf_s(sendBuff, 100, "Ack: %s", recvBuff);
sendto(socksrv, sendBuff, strlen(sendBuff) + 1, 0,
(SOCKADDR*)&addrclie,len);
}
这里的recvfrom函数,第一个参数表示主机接收消息,而recv函数,第一个参数表示分机接收消息,这里没有将recv函数写出来,第四个参数默认为0、
sprintf_s第一个参数表示存储空间,第二个表示要写入的字符串,第三个表示占位符所代表的字符串,即把"ACk:...."写入sendBuff
最后一步,关闭套接字