C++ 黑客编程揭秘与防范(第3版)
上QQ阅读APP看书,第一时间看更新

2.2.2 基于UDP的通信

1.服务器端代码

基于UDP协议的服务器端程序不会去监听端口和等待客户端的请求连接,因此UDP的服务端程序相对于TCP的服务端程序来说代码更短。基于UDP的服务端代码如下:

        #include <stdio.h>
        #include <winsock2.h>
        #pragma comment (lib, "ws2_32")

        int main()
        {
            WSADATA wsaData;
            WSAStartup(MAKEWORD(2, 2), &wsaData);

            // 创建套接字
            SOCKET sServer = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

            // 对sockaddr_in结构体填充地址、端口等信息
            struct sockaddr_in ServerAddr;
            ServerAddr.sin_family = AF_INET;
            ServerAddr.sin_addr.S_un.S_addr = inet_addr("10.10.30.12");
            ServerAddr.sin_port = htons(1234);
            // 绑定套接字与地址信息
            bind(sServer, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr));

            // 接收消息
            char szMsg[MAXBYTE] = { 0 };
            struct sockaddr_in ClientAddr;
            int nSize = sizeof(ClientAddr);
            recvfrom(sServer, szMsg, MAXBYTE, 0, (SOCKADDR*)&ClientAddr, &nSize);
            printf("Client Msg: %s \r\n", szMsg);

            printf("ClientIP=%s:%d\r\n",inet_ntoa(ClientAddr.sin_addr),
                      ntohs(ClientAddr.sin_port));

            // 发送消息
            lstrcpy(szMsg, "Hello Client!\r\n");
            nSize = sizeof(ClientAddr);
            sendto(sServer,szMsg,strlen(szMsg)+sizeof(char),0,(SOCKADDR*)&ClientAddr,nSize);

            WSACleanup();

            return 0;
          }

2.客户端代码

基于UDP客户端的代码相对于TCP的客户端代码来讲,不需要调用connect()函数进行连接,省去了TCP的“三次握手”的过程,可以直接发送数据给服务器。基于UDP的客户端代码如下:

        #include <stdio.h>
        #include <winsock2.h>
        #pragma comment (lib, "ws2_32")

        int main()
        {
            WSADATA wsaData;
            WSAStartup(MAKEWORD(2, 2), &wsaData);

            // 创建套接字
            SOCKET sClient = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

            // 对sockaddr_in结构体填充地址、端口等信息
            struct sockaddr_in ServerAddr;
            ServerAddr.sin_family = AF_INET;
            ServerAddr.sin_addr.S_un.S_addr = inet_addr("10.10.30.12");
            ServerAddr.sin_port = htons(1234);

            // 发送消息
            char szMsg[MAXBYTE] = { 0 };
            lstrcpy(szMsg, "Hello Server!\r\n");
            int nSize = sizeof(ServerAddr);
            sendto(sClient,szMsg,strlen(szMsg)+sizeof(char),0,(SOCKADDR*)&ServerAddr,nSize);

            // 接收消息
            nSize = sizeof(ServerAddr);
            recvfrom(sClient, szMsg, MAXBYTE, 0, (SOCKADDR*)&ServerAddr, &nSize);
            printf("Server Msg: %s \r\n", szMsg);

            WSACleanup();

            return 0;
        }

在完成服务端和客户端代码后,将代码都进行编译连接,然后先运行服务器端的程序,再运行客户端的程序,这时可以看到服务器端和客户端能够正常接收到对方发来的字符串信息,说明通信成功。