天天看點

Windows系統UDP資料通信

發送資料:

#include<Windows.h>
//網絡程式設計在Windows平台上有倆個主要版本:Winsock1和Winsock2
#include <WinSock.h>
#pragma comment(lib, "WSock32.Lib")
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#define SCANPORT 6000  //自定義端口号

    //定義網絡子產品的版本MAKEWORD(2,1),具體試試看那個能用
    WORD socketVersion = MAKEWORD(2,2);
    WSADATA wsaData;
    if(WSAStartup(socketVersion, &wsaData) == 0){
        qDebug()<<"網絡子產品加載成功,可以進行網絡通信";
    }
    //設定目标機的IP位址和端口
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;//協定族IPv4
    sin.sin_port = htons(SCANPORT);//htons将主機位元組序轉為網絡位元組序,端口号
    sin.sin_addr.S_un.S_addr = inet_addr(Addr.c_str());;//網絡順序的廣播IP位址
    //設定本機要使用的IP位址和端口
    struct sockaddr_in sinlocal;
    sinlocal.sin_family = AF_INET;//協定族IPv4
    sinlocal.sin_port = htons(SCANPORT);//htons将主機位元組序轉為網絡位元組序,端口号
    sinlocal.sin_addr = inet_addr(_localAddr.c_str());;
    //定義UDP套接字句柄
    int sclient = socket(AF_INET, SOCK_DGRAM, 0);//SOCK_DGRAM指定為UDP
    //綁定本機的IP端口
    ret = bind(sclient, (struct sockaddr*)&sinlocal, sizeof(struct sockaddr_in));//綁定本機資訊
    //将資料發到目标機:句柄,資料,資料長度,預設0,目标機位址
    ret = sendto(sclient, Data, 128, 0, (sockaddr *)&sin, sizeof(sin));

//關閉套接字
closesocket(sclient);
           

接收資料:

#include<Windows.h>
//網絡程式設計在Windows平台上有倆個主要版本:Winsock1和Winsock2
#include <WinSock.h>
#pragma comment(lib, "WSock32.Lib")
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#define SCANPORT 6000  //自定義端口号
void main(){
    //定義網絡子產品的版本MAKEWORD(2,1),具體試試看那個能用
    WORD socketVersion = MAKEWORD(2,2);
    WSADATA wsaData;
    if(WSAStartup(socketVersion, &wsaData) == 0){
        qDebug()<<"網絡子產品加載成功,可以進行網絡通信";
    }

    //接收資料
    int sclient_recv = socket(AF_INET, SOCK_DGRAM, 0/*UDP*/);
    //設定本機用來接收資料的IP位址和端口号
    struct sockaddr_in sin_recv;//定義接收時的協定,端口等
    sin_recv.sin_family = AF_INET;
    sin_recv.sin_port = htons(SCANPORT);
    sin_recv.sin_addr.s_addr = htonl(INADDR_ANY);//設定接收時來者不拒所有IP都收

    //将本機用來接收資料的句柄和IP端口連接配接在一起
    ret = bind(sclient_recv, (struct sockaddr*)&sin_recv, sizeof(struct sockaddr_in));​​​​​​​
    
    //要接收的IP資訊集合,最多64個,
    //個人了解就是用來存放所有需要監聽的本機網絡套接字(也就是本機哪幾個IP端口需要監聽有沒有資料到來)
    fd_set l_reads;
    FD_ZERO(&l_reads);//将l_reads清空
    FD_SET(sclient_recv, &l_reads);//将sclient_recv加入l_reads集合
    //控制等待時間
    timeval l_timeout;
    l_timeout.tv_sec = 5;
    l_timeout.tv_usec = 0;
    while(1){
        //檢查fd_set容器裡的socket是否有信号到來,超過等待時間,則表示沒收到資料
        int l_nErr = select(sclient_recv, &l_reads, NULL, NULL, &l_timeout);

        // FD_ISSET判斷fd_set裡的sclient_recv有沒有收到資料
        if(FD_ISSET(sclient_recv, &l_reads)){
            //記錄接收到遠端資料的計算機的IP端口資訊
            struct sockaddr_in sin;

            int len = sizeof(sin);
            char recvData[128];//用來存放收到的資料
            memset(recvData,0,128);
            //擷取到的資料包:套接字,資料容器,包大小,0,目标機的資訊
            ret = recvfrom(sclient_recv, recvData, 128, 0, (sockaddr *)&sin, &len); 
        }
    }
}
//關閉套接字
closesocket(sclient_recv);
           

繼續閱讀