03.UDP sockets and raw sockets

UDP socket

Note that in UDP sockets, recvfrom and sendto are used

  • API:

    • recvfrom:

      Receive packets and store source address (UDP)

    • Function prototype:

      int WSAAPI recvfrom(
        [in] SOCKET s,
        [out] char *buf,
        [in] int len,
        [in] int flags,
        [out] sockaddr *from,
        [in, out, optional] int *fromlen
      );
      
    • parameter:

      • s: descriptor identifying the bound socket
      • buf: buffer for incoming data
      • len: buffer length
      • flags: used to modify function calling behavior
      • from: Pointer to sockaddr structure, the source address will be retained in this buffer
      • fromlen: size of the buffer pointed to by from
    • return value:

      If no error occurred, the recvfrom function returns the number of bytes received

  • UDP Server:

    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <iostream>
    #include <WinSock2.h>
    #pragma comment(lib,"ws2_32.lib")
    
    int main() {<!-- -->
    WORD wVersionRequested = MAKEWORD(2, 2);
    WSAData lpWSAData;
    if (WSAStartup(wVersionRequested, & amp;lpWSAData)) {<!-- -->
    std::cout << "WSAStartup Error!" << std::endl;
    return -1;
    }
    
    //SOCKADDR_IN structure is used to specify the transmission address and port of the AF_INET address series
    sockaddr_in saddr;
    saddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(50123);
    
    SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {<!-- -->
    return -1;
    }
    char opt;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, & amp;opt, sizeof(opt));
    
    int nRet = bind(sock, (sockaddr*) & amp;saddr, sizeof(saddr));
    
    sockaddr_in raddr;
    int nLength = sizeof(sockaddr);
    char szReadBuffer[50]{<!-- --> 0 };
    while (true) {<!-- -->
    nRet = recvfrom(sock, szReadBuffer, 50, 0, (sockaddr*) & amp;raddr, & amp;nLength);
    if (nRet < 0) {<!-- -->
    return -1;
    }
    std::cout << "data:" << szReadBuffer << std::endl;
    std::cout << "Please enter:";
    char szBuffer[50]{<!-- --> 0 };
    std::cin >> szBuffer;
    sendto(sock, szBuffer, strlen(szBuffer), 0, (sockaddr*) & amp;raddr, sizeof(sockaddr));
    }
    WSACleanup();
    system("pause");
    return 0;
    }
    
  • UDP Client:

    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <iostream>
    #include <WinSock2.h>
    #pragma comment(lib,"ws2_32.lib")
    
    int main() {<!-- -->
    
    WORD wVersionRequested = MAKEWORD(2, 2);
    WSAData lpWSAData;
    WSAStartup(wVersionRequested, & lpWSAData);
    
    sockaddr_in saddr;
    saddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(50123);
    
    SOCKET SocClient = socket(AF_INET, SOCK_DGRAM, 0);
    if (SocClient < 0) {<!-- -->
    return -1;
    }
    
    char opt;
    setsockopt(SocClient, SOL_SOCKET, SO_REUSEADDR, & amp;opt, sizeof(opt));
    
    char szSendBuffer[50]{<!-- --> 0 };
    char szReadBuffer[50]{<!-- --> 0 };
    sockaddr_in raddr;
    int nLength = sizeof(raddr);
    while (true) {<!-- -->
    std::cout << "Please enter:";
    std::cin >> szSendBuffer;
    sendto(SocClient, szSendBuffer, strlen(szSendBuffer), 0, (sockaddr*) & amp;saddr, sizeof(sockaddr));
    recvfrom(SocClient, szReadBuffer, 50, 0, (sockaddr*) & amp;raddr, & amp;nLength);
    std::cout << "Server:" << szReadBuffer << std::endl;
    }
    closesocket(SocClient);
    WSACleanup();
    system("pause");
    return 0;
    }
    

Raw socket

  • Server:
    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <iostream>
    #include <WinSock2.h>
    #pragma comment(lib,"ws2_32.lib")
    
    typedef struct _IP_HEADER {<!-- -->
    //Version information, header length
    char cVersionAndHeaderLen;
    \t//Service type
    char vTypeOfServer;
    //Data packet length
    short sTotalLenOfPacket;
    //Packet ID
    short sPacketID;
    //fragmentation information
    short sSliceinfp;
    //survival time
    char cTTL;
    \t//agreement type
    char cTypeOfProtocol;
    //Header checksum
    short sCheckSum;
    //Source IP address
    unsigned int uiSrcIP;
    //Destination IP address
    unsigned int uiDestIP;
    }IP_HEADER, *pIP_HEADER;
    
    typedef struct _UDP_HEADER {<!-- -->
    //Source port number
    unsigned short usSourPort;
    //destination port number
    unsigned short usDestIPPort;
    //Data packet length
    unsigned short usLength;
    //checksum
    unsigned short usCheckSum;
    }UDP_HEADER, pUDP_HEADER;
    
    int main() {<!-- -->
    WORD wVersionRequested = MAKEWORD(2, 2);
    WSAData lpWSAData;
    WSAStartup(wVersionRequested, & lpWSAData);
    
    sockaddr_in SAddr;
    SAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    SAddr.sin_family = AF_INET;
    SAddr.sin_port = htons(50123);
    \t
    SOCKET SocSrv = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
    if (SocSrv < 0) {<!-- -->
    return -1;
    }
    
    char opt;
    setsockopt(SocSrv, SOL_SOCKET, SO_REUSEADDR, & amp;opt, sizeof(opt));
    
    int nRet = bind(SocSrv, (sockaddr*) & amp;SAddr, sizeof(SAddr));
    if (nRet < 0) {<!-- -->
    return -1;
    }
    
    char szReadBuffer[500]{<!-- --> 0 };
    sockaddr_in raddr;
    int nLength = sizeof(sockaddr);
    while (true) {<!-- -->
    std::cout << "waiting......" << std::endl;
    nRet = recvfrom(SocSrv, szReadBuffer, 500, 0, (sockaddr*) & amp;raddr, & amp;nLength);
    IP_HEADER iph;
    UDP_HEADER udph;
    memcpy( & amp;iph, szReadBuffer, 20);
    memcpy( & amp;udph, szReadBuffer + 20, 8);
    int srcp = ntohs(udph.usSourPort);
    in_addr ias, iad;
    ias.s_addr = iph.uiSrcIP;
    iad.s_addr = iph.uiDestIP;
    char Temp[0x100]{<!-- --> 0 };
    strcpy_s(Temp, inet_ntoa(iad));
    std::cout << "SrcIP:" << inet_ntoa(iad) << "Port:" << ntohs(udph.usSourPort) << std::endl;
    std::cout << "DestIP:" << inet_ntoa(iad) << "Port:" << ntohs(udph.usDestIPPort) << std::endl;
    std::cout << "recv data:" << szReadBuffer + 28 << std::endl;
    }
    closesocket(SocSrv);
    WSACleanup();
    system("pause");
    return 0;
    }
    
  • Client:
    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <iostream>
    #include <WinSock2.h>
    #pragma comment(lib,"ws2_32.lib")
    
    int main() {<!-- -->
    
    WORD wVerSionRequested = MAKEWORD(2, 2);
    WSAData lpWSAData;
    WSAStartup(wVerSionRequested, & amp;lpWSAData);
    
    sockaddr_in saddr;
    saddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(50123);
    \t
    SOCKET SocClient = socket(AF_INET, SOCK_DGRAM, 0);
    if (SocClient < 0) {<!-- -->
    return -1;
    }
    
    char opt;
    setsockopt(SocClient, SOL_SOCKET, SO_REUSEADDR, & amp;opt, sizeof(opt));
    
    char szSendBuffer[500]{<!-- --> 0 };
    std::cout << "input:";
    std::cin >> szSendBuffer;
    sendto(SocClient, szSendBuffer, strlen(szSendBuffer), 0, (sockaddr*) & amp;s5addr, sizeof(sockaddr)); WSACleanup();
    closesocket(SocClient);
    WSACleanup();
    system("pause");
    return 0;
    }