因为UDP不是面向连接的,且不可靠的,所以发送端在调用sendto
之后,就算sendto
返回成功,也不代表接收端一定收到了数据,可能接收端压根都没启动,也是有可能的。不能根据sendto
的返回值来确保接收端一定收到了数据。如果需要数据传输的可靠性得到保证,可以使用TCP或者通过业务逻辑来保证。
#include
#pragma comment(lib, "Ws2_32.lib")
void SendLogic() {
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(1, 0);
WSAStartup(wVersionRequested, &wsaData);
SOCKET socket = ::WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, nullptr, 0, 0);
if (socket == INVALID_SOCKET) {
printf("WSASocket failed, error=%d\n", WSAGetLastError());
return;
}
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(6000); // 接收端端口
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 接收端IP
char buf[100] = { "hello" };
int err = sendto(socket, buf, strlen(buf), 0, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
if (err == SOCKET_ERROR) {
printf("sendto failed, error=%d\n", WSAGetLastError());
return;
}
printf("[SEND] %s OK\n", buf);
WSACleanup();
}
int main()
{
SendLogic();
getchar();
return 0;
}
因为UDP不是面向连接的,所以接收端不用listen,也不用accept,只需要绑定到指定的端口和地址即可。
recvfrom
是同步的,会阻塞住等待数据的到来。如果要使用异步方式,可以使用WSARecvFrom
结合ICOP的方式来实现。
#include
#pragma comment(lib, "Ws2_32.lib")
void RecvLogic() {
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(1, 0);
WSAStartup(wVersionRequested, &wsaData);
SOCKET socket = ::WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, nullptr, 0, 0);
if (socket == INVALID_SOCKET) {
printf("WSASocket failed, error=%d\n", WSAGetLastError());
return;
}
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(6000); // 端口
addr.sin_addr.s_addr = INADDR_ANY; // 任意IP地址
int err = bind(socket, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
if (err == SOCKET_ERROR) {
printf("bind failed, error=%d\n", WSAGetLastError());
return;
}
while (true) { // TODO:未考虑退出的情况
char buf[100] = { 0 };
int fromlen = sizeof(addr);
err = recvfrom(socket, buf, 100, 0, reinterpret_cast(&addr), &fromlen);
if (err == SOCKET_ERROR) {
printf("recvfrom failed, error=%d\n", WSAGetLastError());
return;
}
printf("[RECV] %s\n", buf);
}
WSACleanup();
}
int main()
{
RecvLogic();
getchar();
return 0;
}