自定义帧结构如下:
需要用到的东西包括子系统编号,设备编号,信息类型,数据体长度,数据体
作为发送方,定义子系统编号为10,设备编号为1,信息类型假设为22,信息类型22的数据体长度为定值78
则代码如下:
client.cpp
// data_frame.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <string> #include <iostream> #include <winsock2.h> #pragma comment(lib , "Ws2_32.lib") using namespace std; #pragma pack(push) //保存对齐状态 #pragma pack(1) struct type_22_state_data { short a; short b; char c; }; struct type_22_data { short a; short b; int c; struct type_22_state_data d[14]; };//78个字节 struct type_22 { char header[11]; struct type_22_data data; type_22() { header[0]=10; header[1]=1; header[8]=22; header[9]=0; header[10]=78; } }; #pragma pack(pop)//恢复对齐状态 int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData; if(WSAStartup(MAKEWORD(2,1), &wsaData)) { printf("winsock init failed!\n"); return 1; } struct sockaddr_in server; int len = sizeof(server); server.sin_family = AF_INET; server.sin_port = htons(8000); /* 服务器监听端口 */ server.sin_addr.s_addr = inet_addr("127.0.0.1"); /* 服务器地址 */ char buf[1024]; struct type_22 a3; a3.data.a=htons(1); a3.data.b=htons(2); a3.data.c=htons(3); a3.data.d[0].a=htons(100); SOCKET sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if(sendto(sock_fd,(char *)&a3,sizeof(struct type_22),0,(struct sockaddr*)&server,sizeof(struct sockaddr))!=SOCKET_ERROR) { cout<<"send succeed"<<endl; return 0; } else { cout<<"send error"<<endl; } return 0; }
#include "stdafx.h" #include <stdio.h> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") #define SERVER_PORT 8000 int main() { /* init winsock */ WSADATA wsaData; if(WSAStartup(MAKEWORD(2,1), &wsaData)) { printf("winsock init failed!\n"); return 1; } struct sockaddr_in local; struct sockaddr_in from; int len = sizeof(struct sockaddr_in); local.sin_family = AF_INET; local.sin_port = htons(SERVER_PORT); /* 监听端口 */ local.sin_addr.s_addr = INADDR_ANY; /* 本机 */ /* create udp socket */ SOCKET sock_fd = socket(AF_INET, SOCK_DGRAM, 0); bind(sock_fd, (struct sockaddr *)&local, sizeof(local)); char bufferIn[1024]; while(1) { bufferIn[0] = '\0'; printf("waiting...\n"); int nbyte=0; if((nbyte=recvfrom(sock_fd, bufferIn, sizeof(bufferIn), 0, (struct sockaddr *)&from, &len)) != SOCKET_ERROR) { printf("From %s:\n", inet_ntoa(from.sin_addr)); printf("nbyte is %d",nbyte); // printf("header is %d %d %d %d %d:\n",bufferIn[0],bufferIn[1],bufferIn[8],bufferIn[9],bufferIn[10]); for(int i=0;i<nbyte;++i) printf("%x ",bufferIn[i]); } } closesocket(sock_fd); WSACleanup(); return 0; }
运行结果如下:
客户端为:
服务器端为:
结果显而易见是正确的~~注意server.cpp中htons函数的使用,是为了以网络字节序传递过去,不然其中的0 0 0 64 会变成 64 0 0 0,因为x86架构的机器默认是小端法,网络字节序是大端,因此会有64 0 0 0 的效果,因此为开发平台无关的程序,特别要注意这点。