程序代碼開發環境爲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;
}
先運行客戶端,再運行服務器端,其最終數據接收如圖所示: