關於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; }