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

关于P2P通讯原理与实现你们能够参见参见P2P通讯原理与实现(C语言)文档,我这里就不在详述了。windows

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

/// <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是命令执行的数据内容。函数

因为在通信过程当中,这个信息结构体会常常被用到,所以须要定义一个初始化结构指针的函数。.net

/// <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,这个函数咱们将在后面根据业务进行不断的扩展来使用。code

/// <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服务的方式进行改造。server

int main()
{
	HANDLE hMutex = CreateMutex(NULL, false, (LPCWSTR)"James");
	p2pserver(9000, "");
	CloseHandle(hMutex);
    return 0;
}
相关文章
相关标签/搜索