Windows socket编程 udp协议传送封装自定义帧

最近在出差,要在内网做个发送自定义帧结构的数据的程序,一时间没做过这类东西,在网上学习了许多新的概念,也回顾了网络程序设计课上所学的关于网络字节序的相关知识,总结如下:

自定义帧结构如下:


需要用到的东西包括子系统编号,设备编号,信息类型,数据体长度,数据体

作为发送方,定义子系统编号为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;
}

server.cpp

#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 的效果,因此为开发平台无关的程序,特别要注意这点。


你可能感兴趣的:(windows,socket)