windows下同一臺主機實現udp通信:結構體數據傳輸

程序代碼開發環境爲QT,在使用socket時,其工程文件XXXXX.pro中需添加以下代碼:

利用udp發送數據時,可能會發送不同類型的數據,多種類型數據通過一條udp報文發送需要,因此需要建立一個結構體對需要發送的數據進行定義。但是udp發送的是char型參數,因此需要將結構體轉換爲char型。

LIBS += -lWS2_32

頭文件:

//head.h
#ifndef HEAD_H
#define HEAD_H
int socket_recv(void);

typedef struct DATASENT
{
    int i;
    long tt;
    double dv;
    float fv;
    unsigned int uiv;
}DATASENT;
#endif // HEAD_H

服務器端:

    發送時需要轉換城char型

#include "head.h"
#include <stdio.h>
#include <winsock2.h>


int main(int argc, char *argv[])
{
    printf("Hello World!\n");
    socket_send();
    return 0;
}

int socket_send(void){
    printf("sendto starting...\n");
    //初始化socket
    DWORD ver;
    WSADATA WSAData;
    //在調用WSAStartup要告知Windows要使用什麼版本的socket

    ver = MAKEWORD(1,1);

    WSAStartup(ver,&WSAData); //Windows 要求,只要使用socket,第一步必須調用這個函數
    //初始化socket完成

    SOCKET st = socket(AF_INET,SOCK_DGRAM,0);//建立一個socket
    struct sockaddr_in addr;
    memset(&addr,0,sizeof(addr));//初始化addr

    addr.sin_family = AF_INET;
    addr.sin_port = htons(6000);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    struct DATASENT data_sent;
    memset(&data_sent,0,sizeof(DATASENT));
    data_sent.i =6;
    data_sent.tt = 4;
    data_sent.dv = 1.23;
    data_sent.fv = 0.50f;
    data_sent.uiv = 2534;

    char buf[1024]={0};
    memcpy(&buf,&data_sent,sizeof(data_sent));
    sendto(st,buf,sizeof(data_sent),0,(struct sockaddr *)&addr,sizeof(struct sockaddr));


    closesocket(st);

    WSACleanup();//釋放win socket 的相關的資源
    return 0;
}

客戶端:

     要定義和發送方完全一致的結構體,並進行char到結構體的逆轉換才能正確接收數據

#include "head.h"
#include <stdio.h>
#include <winsock2.h>
int main(int argc, char *argv[])
{

    socket_recv();
    return 0;
}

int socket_recv(void){
    struct DATASENT data_recv;

    printf("recv before socket_recv starting...\n");
    //初始化socket
    DWORD ver;
    WSADATA WSAData;
    //在調用WSAStartup要告知Windows要使用什麼版本的socket
    ver = MAKEWORD(1,1);
    WSAStartup(ver,&WSAData); //Windows 要求,只要使用socket,第一步必須調用這個函數
    //初始化socket完成

    SOCKET st = socket(AF_INET,SOCK_DGRAM,0);//建立一個socket
    struct sockaddr_in addr;
    memset(&addr,0,sizeof(addr));//初始化addr
    addr.sin_family = AF_INET;
    addr.sin_port = htons(6000);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if(bind(st,(struct sockaddr *)&addr,sizeof(struct sockaddr))){
        printf("bind error...\n");
        return -1;
    } //當端口號和程序綁定
    printf("recv before...\n");
    char buf[1024]={0};
    struct sockaddr_in src_addr;
    int len = sizeof(struct sockaddr);
    memset(buf,0,sizeof(buf));
    recvfrom(st,buf,sizeof(buf),0,(struct sockaddr *)&src_addr,&len);

    memset(&data_recv,0,sizeof(DATASENT));
    memcpy(&data_recv,&buf,sizeof(data_recv)+1);

    printf("src_ip:%s\n src_port:%d\n",inet_ntoa(src_addr.sin_addr),ntohs(src_addr.sin_port));

    printf("dv:%2.2f,fv:%2.2f,i:%d,tt:%ld;uiv:%d\n",data_recv.dv,data_recv.fv,data_recv.i,data_recv.tt,data_recv.uiv);


    closesocket(st);
    WSACleanup();//釋放win socket 的相關的資源
    return 0;
}

先運行客戶端,再運行服務器端,其最終數據接收如圖所示:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章