网络协议 -- UDP协议(2)单播

一、发送端

因为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;
}

你可能感兴趣的:(☆,网络编程,网络协议)