Windows网络编程(基础篇2)

无连接通信UDP

无连接通信是通过UDP/IP协议完成的。UDP不能确保可靠的数据传输,但能将数据发送到过个目标,或者接收多个源数据。

  1. UDP通信不用调用listen和accept。接收函数recvfrom,和WSARecvFrom

    int recvfrom(
     _In_        SOCKET          s,
     _Out_       char            *buf,
     _In_        int             len,
     _In_        int             flags,//一般填0,具体看MSDN
     _Out_       struct sockaddr *from,//返回接收端的地址信息
     _Inout_opt_ int             *fromlen //指向地址结构的长度
    );
    int WSARecvFrom(
     _In_    SOCKET                             s,
     _Inout_ LPWSABUF                           lpBuffers,
     _In_    DWORD                              dwBufferCount,
     _Out_   LPDWORD                            lpNumberOfBytesRecvd,
     _Inout_ LPDWORD                            lpFlags,
     _Out_   struct sockaddr                    *lpFrom,
     _Inout_ LPINT                              lpFromlen,
     _In_    LPWSAOVERLAPPED                    lpOverlapped,
     _In_    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    );
    • UDP接收端应用程序
    
    #include<winsock2.h>
    
    
    #include<Ws2tcpip.h>
    
    
    #pragma comment(lib,"WS2_32")
    
    int main(void)
    {
    WSADATA wsaData;
    SOCKET  receivingSocket;
    SOCKADDR_IN  ReceiverAddr;
    int Port = 5150;
    char ReceiveBuf[1024];
    int BufLength = 1024;
    SOCKADDR_IN SenderAddr;
    int SenderAddrSize = sizeof(SenderAddr);
    
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    
    //创建一个新的套接字来接收数据报
    receivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    
    //建立一个SOCKADDR_IN结构,这个结构将告知我们想要使用5150端口来接收来自所有接口的数据报
    ReceiverAddr.sin_family = AF_INET;
    ReceiverAddr.sin_port = htons(Port);
    inet_pton(AF_INET, INADDR_ANY, (void*)&ReceiverAddr.sin_addr.S_un.S_addr);
    
    //使用bind将这个地址信息和套接字关联起来
    bind(receivingSocket, (SOCKADDR*)&SenderAddr, sizeof(SenderAddr));
    
    //此时可以在绑定套接字上接收数据报了
    recvfrom(receivingSocket, ReceiveBuf, BufLength, 0, (SOCKADDR*)&SenderAddr, &SenderAddrSize);
    
    //应用程序接收完数据报后。关闭套接字
    closesocket(receivingSocket);
    WSACleanup();
    
    return 1;
    }
  2. 发送函数sendto,和WSASendto

    int sendto(
     _In_       SOCKET                s,        //socket描述符
     _In_ const char                  *buf, //数据报缓存地址
     _In_       int                   len,      //数据报长度
     _In_       int                   flags,    //该参数一般为0
     _In_       const struct sockaddr *to,      //数据发往哪里
     _In_       int                   tolen //对方地址长度
    );//返回发送的字节数
    int WSASendTo(
     _In_  SOCKET                             s,
     _In_  LPWSABUF                           lpBuffers,
     _In_  DWORD                              dwBufferCount,
     _Out_ LPDWORD                            lpNumberOfBytesSent,
     _In_  DWORD                              dwFlags,
     _In_  const struct sockaddr              *lpTo,
     _In_  int                                iToLen,
     _In_  LPWSAOVERLAPPED                    lpOverlapped,
     _In_  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    );
    • UDP发送端示例:
    WSADATA wsaData;
    SOCKET SendingSocket;
    SOCKADDR_IN ReceiverAddr;
    int Port = 5150;
    char SendBuf[1024];
    int BufLength = 1024;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    
    SendingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    ReceiverAddr.sin_family = AF_INET;
    ReceiverAddr.sin_port = htons(Port);
    inet_pton(AF_INET, "136.149.3.29", (void*)&ReceiverAddr);
    
    sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR*)&ReceiverAddr, sizeof(ReceiverAddr));
    
    closesocket(SendingSocket);
    WSACleanup();
  3. 常用winsock API。

    • 获取通信方的套接字地址信息,该信息是关于已建立连接的套接字。
    int getpeername(
     _In_    SOCKET          s,     //准备连接的套接字
     _Out_   struct sockaddr *name,
     _Inout_ int             *namelen
    );
    • 获取给定套接字本地接口信息。
    int getsockname(
     _In_    SOCKET          s,
     _Out_   struct sockaddr *name,
     _Inout_ int             *namelen
    );

声明:以上整理于Windows网络编程(第二版)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值