Windows平台上实现P2P服务(二)

关于P2P通信原理与实现大家可以参见参见P2P通信原理与实现(C语言)文档,我这里就不在详述了。

我们先定义一下信息的结构体,用于发送和接受信息:

/// <summary>信息结构的指针型</summary>
typedef struct _message *lp_message;
/// <summary>信息结构</summary>
typedef struct _message
{
	union {
		struct { char buff[1030]; };
		struct { char cmd[6]; char rt_code[32]; char data[992]; };
	};
	SOCKADDR_IN addr;
};

在这个结构体中,我采用了一个union同时定义了两种读取数据和写入数据的格式,一种是整个数据buffer的,另一种是将buffer分为cmd、rt_code和data三部分的。其中cmd为固定6个大写字母的通讯命令,rt_code为32字节的运行码,data是命令执行的数据内容。

由于在通讯过程中,这个信息结构体会经常被用到,因此需要定义一个初始化结构指针的函数。

/// <summary>建立一个服务信息</summary>
lp_message newMessage()
{
	lp_message msg = (lp_message)malloc(sizeof(_message));
	memset(msg->buff, 0, sizeof(_message));
	return msg;
}

关于Socket的连接与侦听,p2pserver函数是UDP通讯的核心函数,在这个函数开始我们首先建立UDP的通讯,打开端口,绑定服务,最后启动侦听循环,不断地接收客户端发送过来的信息,一旦收到有效信息,就将信息交由receivedMessage函数来进行处理。

/// <summary>p2p服务</summary>
void p2pserver(u_short port, char* connstr)
{
	WSADATA msaData;
	if (WSAStartup(MAKEWORD(2, 2), &msaData) != 0)
		ErrorHandle("WSAStartup error!");
	hServer = socket(AF_INET, SOCK_DGRAM, 0);
	SOCKADDR_IN  addrServ;
	addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons(port);

	bind(hServer, (SOCKADDR*)&addrServ, sizeof(SOCKADDR));
	lp_message msg = newMessage();
	int addr_len = sizeof(SOCKADDR_IN);
	while (true)
	{
		int len = recvfrom(hServer, &msg->buff[0], buff_size, 0, (SOCKADDR*)&msg->addr, &addr_len);
		if (len > 6)
		{
			HANDLE h = (HANDLE)_beginthreadex(NULL, 0, &receivedMessage, msg, 0, NULL);
			msg = newMessage();
		}
	}
	closesocket(hServer);
	WSACleanup();
}

处理相应函数为receivedMessage,这个函数我们将在后面根据业务进行不断的扩展来使用。

/// <summary>处理接收到的信息</summary>
unsigned WINAPI receivedMessage(void *arg)
{
	lp_message msg = (lp_message)arg;
	printf("Received a [%s] from client %s, string is: %s\n", msg->cmd, inet_ntoa(msg->from->sin_addr), msg->buf);
	//do anything
	free(msg);
	return 0;
}

最后看看主函数的简单写法,如果想以windows服务的方式进行,可以参照windows服务的方式进行改造。

int main()
{
	HANDLE hMutex = CreateMutex(NULL, false, (LPCWSTR)"James");
	p2pserver(9000, "");
	CloseHandle(hMutex);
    return 0;
}

 

转载于:https://my.oschina.net/u/2308182/blog/1431004

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值