完成端口Accept方式

来源:互联网 发布:杰克棋牌透视软件 编辑:程序博客网 时间:2024/04/30 23:22

文章一:http://baike.soso.com/v5865322.htm

http://wenku.baidu.com/view/17eb0c2f0066f5335a812136.html

 

文章二:

http://kevensnowgirl.blog.hexun.com/6811572_d.html

http://xingzhesun.blogbus.com/c1584116/

客户端代码

 

// Client.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <WinSock2.h>#include <stdio.h>//不加ws2_32.lib的话就需要动态的加载#pragma comment(lib, "ws2_32.lib")#define SERVER_ADDRESS "127.0.0.1"#define PORT  5150#define MSGSIZE 1024#define CPORT 7001int _tmain(int argc, _TCHAR* argv[]){//Initialize Window socket libraryWSADATA wsaData;WSAStartup(0x0202, &wsaData);//Create Socket;SOCKET sClient;sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//Connect to ServerSOCKADDR_IN server;memset(&server, 0, sizeof(SOCKADDR_IN));server.sin_addr.S_un.S_addr = inet_addr(SERVER_ADDRESS);server.sin_family = AF_INET;server.sin_port = htons(PORT);int ret = connect(sClient, (sockaddr*)&server, sizeof(SOCKADDR_IN));if(ret == SOCKET_ERROR){printf("connet error = %d \n", WSAGetLastError());goto exit;}//send messagechar szMessage[MSGSIZE];while(true){printf("Send:");gets(szMessage);if(0 == strcmp("exit" , szMessage)){goto exit;}//send messagesend(sClient, szMessage, sizeof(szMessage), 0);memset(szMessage, 0, sizeof(szMessage));//receive messageret = recv(sClient, szMessage, MSGSIZE, 0);szMessage[ret] = '\0';printf("REceived [%d bytes]: '%s'\n ", ret, szMessage);}exit:closesocket(sClient);WSACleanup();return 0;}


服务器端代码

 

// server_CompletionPort.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <WinSock2.h>#pragma comment(lib, "ws2_32.lib")#define PORT 5150#define MSGSIZE 1024typedef enum{RECV_POSTED}OPERATION_TYPE;typedef struct{WSAOVERLAPPED overlap;WSABUF Buffer;char szMessage[MSGSIZE];DWORD NumberOfBytesRecvd;DWORD Flags;OPERATION_TYPE OperationType;}PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;DWORD WINAPI WorkerThread(LPVOID CompletionPortID){HANDLE  CompletionPort  = (HANDLE)CompletionPortID;DWORD dwBytesTransferred;SOCKET sClient;LPPER_IO_OPERATION_DATA lpPerIOData = NULL;while(true){//this method to check whether the completionPort queue exist request,//if exist, it will run the following code, if not exist, it will waitingGetQueuedCompletionStatus(CompletionPort,&dwBytesTransferred,(unsigned long*)&sClient,(LPOVERLAPPED*)&lpPerIOData,INFINITE);if(dwBytesTransferred == 0xFFFFFFFF){return 0;}if(lpPerIOData->OperationType == RECV_POSTED){if(dwBytesTransferred == 0){//connection was closed by clientclosesocket(sClient);HeapFree(GetProcessHeap(), 0, lpPerIOData);}else{lpPerIOData->szMessage[dwBytesTransferred] = '\0';send(sClient, lpPerIOData->szMessage, dwBytesTransferred, 0);//launch another asynchronous operation for sClient///*********************************************************memset(lpPerIOData, 0 , sizeof(PER_IO_OPERATION_DATA));lpPerIOData->Buffer.len = MSGSIZE;lpPerIOData->Buffer.buf = lpPerIOData->szMessage;lpPerIOData->OperationType = RECV_POSTED;WSARecv(sClient,&lpPerIOData->Buffer,1,&lpPerIOData->NumberOfBytesRecvd,&lpPerIOData->Flags,&lpPerIOData->overlap,NULL);///*********************************************************}}}}int _tmain(int argc, _TCHAR* argv[]){//1. Initialize Windows Socket libraryWSADATA wsaData;WSAStartup(0x0202, &wsaData);//*2. Create Completion port, save its handle, and this handle will usefulHANDLE CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);//*3. Create Worker Thread//3.1 the thread number is same as the Processor number//3.2 this thread is use to commnute with the clientSYSTEM_INFO systeminfo;GetSystemInfo(&systeminfo);DWORD dwThreadId;for(int i=0 ; i < systeminfo.dwNumberOfProcessors; i++){CreateThread(NULL, 0, WorkerThread, CompletionPort, 0, &dwThreadId);}SOCKET sListen, sClient= NULL;//4. Create listening socketsListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//5. BindSOCKADDR_IN local, client;local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);local.sin_family = AF_INET;local.sin_port = htons(PORT);bind(sListen, (sockaddr*)&local, sizeof(SOCKADDR_IN));printf("Binded\n");//6. Listenlisten(sListen, 3);printf("Listened\n");LPPER_IO_OPERATION_DATA lpPerIOData = NULL;int nLen = sizeof(sockaddr);while(true){printf("Accepting...\n");//7. accept a connectionsClient = accept(sListen, (sockaddr*)&client, &nLen);printf("Accepted client:%s : %d, &%d \n", inet_ntoa(client.sin_addr), ntohs(client.sin_port),WSAGetLastError());//*8. Associate the newly arrived client socket with completion port//8.1 Whenever the client connect to server, use this method again, //    but this time its function is to bind with the new Socket with the completionPort//8.2 After this method create, the preparetion is completed. following with send or recv it.CreateIoCompletionPort((HANDLE)sClient, CompletionPort, (DWORD)sClient, 0);//Launch an asynchronous operation for new arrived connetion///*********************************************************lpPerIOData = (LPPER_IO_OPERATION_DATA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PER_IO_OPERATION_DATA));lpPerIOData->Buffer.len = MSGSIZE;lpPerIOData->Buffer.buf = lpPerIOData->szMessage;lpPerIOData->OperationType = RECV_POSTED;WSARecv(sClient,&lpPerIOData->Buffer,1,&lpPerIOData->NumberOfBytesRecvd,&lpPerIOData->Flags,&lpPerIOData->overlap,NULL);///*********************************************************}PostQueuedCompletionStatus(CompletionPort, 0xFFFFFFFF, 0, NULL);CloseHandle(CompletionPort);closesocket(sListen);WSACleanup();return 0;}


 

 

原创粉丝点击