C/C++ Windows API——Udp

// UdpDemo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include 
#include //inet_ntop, inet_pton

#pragma comment(lib, "WS2_32.lib")
#define BUF_SIZE 64

int main()
{
    int ret;

    WORD wVersionRequested = MAKEWORD(2, 2);
    WSADATA wsaData;

    ret = WSAStartup(wVersionRequested, &wsaData);
    if (ret != 0) {
        printf("WSAStartup() called failed!\n");
        return -1;
    }
    else {
        printf("WSAStartup() called success!\n");
    }

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
        //若不是所请求的版本号2.2,则终止WinSock库的使用 
        WSACleanup();
        return -1;
    }

    /*
    AF 表示ADDRESS FAMILY 地址族
    PF 表示PROTOCL FAMILY 协议族
    所以在windows中AF_INET与PF_INET完全一样
    而在Unix/Linux系统中,在不同的版本中这两者有微小差别,对于BSD,是AF,对于POSIX是PF
    #define PF_INET         AF_INET

    #define SOCK_STREAM     1               // stream socket
    #define SOCK_DGRAM      2               // datagram socket
    #define SOCK_RAW        3               // raw-protocol interface
    #define SOCK_RDM        4               // reliably-delivered message
    #define SOCK_SEQPACKET  5               // sequenced packet stream

    typedef enum {
        #if(_WIN32_WINNT >= 0x0501)
        IPPROTO_HOPOPTS       = 0,  // IPv6 Hop-by-Hop options
        #endif//(_WIN32_WINNT >= 0x0501)
        IPPROTO_ICMP          = 1,
        IPPROTO_IGMP          = 2,
        IPPROTO_GGP           = 3,
        #if(_WIN32_WINNT >= 0x0501)
        IPPROTO_IPV4          = 4,
        #endif//(_WIN32_WINNT >= 0x0501)
        #if(_WIN32_WINNT >= 0x0600)
        IPPROTO_ST            = 5,
        #endif//(_WIN32_WINNT >= 0x0600)
        IPPROTO_TCP           = 6,
        #if(_WIN32_WINNT >= 0x0600)
        IPPROTO_CBT           = 7,
        IPPROTO_EGP           = 8,
        IPPROTO_IGP           = 9,
        #endif//(_WIN32_WINNT >= 0x0600)
        IPPROTO_PUP           = 12,
        IPPROTO_UDP           = 17,
        IPPROTO_IDP           = 22,
        #if(_WIN32_WINNT >= 0x0600)
        IPPROTO_RDP           = 27,
        #endif//(_WIN32_WINNT >= 0x0600)

        #if(_WIN32_WINNT >= 0x0501)
        IPPROTO_IPV6          = 41, // IPv6 header
        IPPROTO_ROUTING       = 43, // IPv6 Routing header
        IPPROTO_FRAGMENT      = 44, // IPv6 fragmentation header
        IPPROTO_ESP           = 50, // encapsulating security payload
        IPPROTO_AH            = 51, // authentication header
        IPPROTO_ICMPV6        = 58, // ICMPv6
        IPPROTO_NONE          = 59, // IPv6 no next header
        IPPROTO_DSTOPTS       = 60, // IPv6 Destination options
        #endif//(_WIN32_WINNT >= 0x0501)

        IPPROTO_ND            = 77,
        #if(_WIN32_WINNT >= 0x0501)
        IPPROTO_ICLFXBM       = 78,
        #endif//(_WIN32_WINNT >= 0x0501)
        #if(_WIN32_WINNT >= 0x0600)
        IPPROTO_PIM           = 103,
        IPPROTO_PGM           = 113,
        IPPROTO_L2TP          = 115,
        IPPROTO_SCTP          = 132,
        #endif//(_WIN32_WINNT >= 0x0600)
        IPPROTO_RAW           = 255,

        IPPROTO_MAX           = 256,
        //
        //  These are reserved for internal use by Windows.
        //
        IPPROTO_RESERVED_RAW  = 257,
        IPPROTO_RESERVED_IPSEC  = 258,
        IPPROTO_RESERVED_IPSECOFFLOAD  = 259,
        IPPROTO_RESERVED_WNV = 260,
        IPPROTO_RESERVED_MAX  = 261
    } IPPROTO, *PIPROTO;
    */
    SOCKET udpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

    /*
    //Structure used to store most addresses.
    typedef struct sockaddr {

        #if (_WIN32_WINNT < 0x0600)
            u_short sa_family;
        #else
            ADDRESS_FAMILY sa_family;           // Address family.
        #endif //(_WIN32_WINNT < 0x0600)

            CHAR sa_data[14];                   // Up to 14 bytes of direct address.
    } SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;

    //IPv4 Socket address, Internet style
    typedef struct sockaddr_in {

        #if(_WIN32_WINNT < 0x0600)
            short   sin_family;
        #else //(_WIN32_WINNT < 0x0600)
            ADDRESS_FAMILY sin_family;
        #endif //(_WIN32_WINNT < 0x0600)

        USHORT sin_port;
        IN_ADDR sin_addr;
        CHAR sin_zero[8];
    } SOCKADDR_IN, *PSOCKADDR_IN;

    可以看出sockaddr是通用的,而sockaddr_in是针对Ipv4的
    */
    sockaddr_in sockAddr;
    /*
    Error   C4996   'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
    sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

    IP地址转换函数,可以在将IP地址在“点分十进制”和“二进制整数”之间转换
    inet_pton:将“点分十进制” -> “二进制整数”
    int inet_pton(
        int af,         //地址簇
        const char *src,//源地址
        void *dst       //目的地址
    );
    */
    inet_pton(PF_INET, "127.0.0.1", &sockAddr.sin_addr.S_un.S_addr);
    sockAddr.sin_family = PF_INET;
    sockAddr.sin_port = htons(7777);

    bind(udpSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr));

    sockaddr_in otherAddr;
    int addrLen = sizeof(otherAddr);
    char buf[MAXBYTE] = { 0 };
    recvfrom(udpSocket, buf, MAXBYTE, 0, (SOCKADDR*)&otherAddr, &addrLen);

    const int szAddrlen = 17;
    char szOtherAddr[szAddrlen];
    inet_ntop(PF_INET, (LPVOID)&otherAddr, szOtherAddr, szAddrlen);
    printf("receive from %s:%d, buffer = %s", szOtherAddr, otherAddr.sin_port, buf);

    char *sendMsg = "hello world";
    sendto(udpSocket, sendMsg, strlen(sendMsg) + sizeof(char), 0, (SOCKADDR*)&otherAddr, addrLen);

    closesocket(udpSocket);

    WSACleanup();
    return 0;
}

你可能感兴趣的:(#,Windows,API)