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;
}
相關文章
相關標籤/搜索