18,356
社区成员
发帖
与我相关
我的任务
分享
#define PORT 5150
#define DATA_BUFSZIE 8192
// 单IO操作数据
typedef struct
{
OVERLAPPED oVerlapped;
WSABUF DATABuf;
CHAR Buffer[DATA_BUFSZIE];
DWORD BytesSend, BytesRecv;
}PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;
// 单句柄操作数据
typedef struct
{
SOCKET Socket;
}PER_HANDLE_DATA, *LPPER_HANDLE_DATA;
// 工作线程
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID);
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET localSockListen, acceptSocket;
WSADATA wsadata;
HANDLE completionPort;
SYSTEM_INFO systemInfo;
LPPER_HANDLE_DATA perHandleData;
LPPER_IO_OPERATION_DATA perIoData;
DWORD recvBytes;
DWORD flags;
DWORD threadID;
DWORD ret;
ret = WSAStartup(0x0202, &wsadata);
if (ret != 0)
{
printf("WSAStartup failed with error %d\n", ret);
}
completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (completionPort == NULL)
{
printf("CreateIoCompletionPort failed with error %d\n", GetLastError());
}
GetSystemInfo(&systemInfo);
// 创建完成端口工作线程
for (int i=0; i < systemInfo.dwNumberOfProcessors; i++)
{
HANDLE threadHandle;
threadHandle = CreateThread(NULL, 0, ServerWorkerThread, completionPort, 0, &threadID);
if (threadHandle == NULL)
{
printf("CreateThread failed with error %d\n", GetLastError());
return 0;
}
CloseHandle(threadHandle);
}
// 创建监听端口
localSockListen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
if (localSockListen == INVALID_SOCKET)
{
printf("WSASocket() failed with error %d\n", WSAGetLastError());
return 0;
}
SOCKADDR_IN localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(PORT);
// 绑定Socket
ret = bind(localSockListen, (LPSOCKADDR)&localAddr, sizeof(SOCKADDR_IN));
if (ret == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return 0;
}
// 启动监听
if (listen(localSockListen, 10000) == SOCKET_ERROR)
{
printf("listen() failed with error %d\n", WSAGetLastError());
return 0;
}
// 接收连接请
while (TRUE)
{
acceptSocket = WSAAccept(localSockListen, NULL, NULL, NULL, 0);
if (acceptSocket == SOCKET_ERROR)
{
printf("WSAAccept() failed with error %d\n", WSAGetLastError());
return 0;
}
// 创建单句柄数据
perHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR, sizeof(perHandleData));
if (perHandleData == NULL)
{
printf("GlobalAlloc() failed with error %d\n", WSAGetLastError());
return 0;
}
printf("Socket Number %d\n", acceptSocket);
perHandleData->Socket = acceptSocket;
if(CreateIoCompletionPort((HANDLE)acceptSocket, completionPort, (DWORD)perHandleData, 0) == NULL)
{
printf("CreateIoCompletionPort() failed with error %d\n", WSAGetLastError());
return 0;
}
// 创建单IO数据
perIoData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA));
if (perIoData == NULL)
{
printf("GlobalAlloc() failed with error %d\n", WSAGetLastError());
return 0;
}
ZeroMemory(&(perIoData->oVerlapped), sizeof(OVERLAPPED));
perIoData->DATABuf.buf = perIoData->Buffer;
perIoData->DATABuf.len = DATA_BUFSZIE;
perIoData->BytesRecv = 0;
perIoData->BytesSend = 0;
flags = 0;
if (WSARecv(acceptSocket, &(perIoData->DATABuf), 1, &recvBytes, &flags, &(perIoData->oVerlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return 0;
}
}
}
return 0;
}
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE completionPort = (HANDLE)CompletionPortID;
DWORD BytesTransfer;
LPPER_HANDLE_DATA perHandleData;
LPPER_IO_OPERATION_DATA perIoData;
LPOVERLAPPED overLapped;
DWORD sendBytes, recvBytes;
DWORD flags;
while (TRUE)
{
if (GetQueuedCompletionStatus(completionPort, &BytesTransfer, (LPDWORD)&perHandleData, (LPOVERLAPPED*)&perIoData, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus() failed with error %d\n", GetLastError());
return 0;
}
if (BytesTransfer == 0)
{
printf("closing socket %d\n", perHandleData->Socket);
if (closesocket(perHandleData->Socket) == SOCKET_ERROR)
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
return 0;
}
GlobalFree(perHandleData);
GlobalFree(perIoData);
continue;
}
if (perIoData->BytesRecv == 0)
{
perIoData->BytesRecv = BytesTransfer;
perIoData->BytesSend = 0;
}
else
{
perIoData->BytesRecv += BytesTransfer;
}
BytesTransfer = 0;
if (perIoData->BytesRecv > perIoData->BytesSend)
{
ZeroMemory(&(perIoData->oVerlapped), sizeof(OVERLAPPED));
perIoData->DATABuf.buf = perIoData->Buffer + perIoData->BytesSend;
perIoData->DATABuf.len = perIoData->BytesRecv - perIoData->BytesSend;
flags = 0;
if (WSASend(perHandleData->Socket, &perIoData->DATABuf, 1, &sendBytes, 0, &perIoData->oVerlapped, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
return 0;
}
}
}
else
{
perIoData->BytesRecv = 0;
ZeroMemory(&(perIoData->oVerlapped), sizeof(OVERLAPPED));
perIoData->DATABuf.buf = perIoData->Buffer;
perIoData->DATABuf.len = DATA_BUFSZIE;
flags = 0;
if (WSARecv(perHandleData->Socket, &perIoData->DATABuf, 1, &recvBytes, &flags, &perIoData->oVerlapped, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
return 0;
}
}
}
}
}
WSADATA wsadata;
SOCKET serverSocket;
SOCKADDR_IN serverAddr;
DWORD sendBytes, recvBytes;
CHAR buffer[DATA_BUFSIZE] = "hello, server !";
if (WSAStartup(0x0202, &wsadata) != 0)
{
printf("WSAStartup failed with error %d\n", WSAGetLastError());
return 0;
}
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (serverSocket == INVALID_SOCKET)
{
printf("create socket failed with error %d\n", GetLastError());
return 0;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddr.sin_port = htons(PORT);
if (connect(serverSocket, (SOCKADDR*)&serverAddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
printf("connect() failed with error %d\n", WSAGetLastError());
return 0;
}
printf("connection successful! server Port : %d\n", serverSocket);
sendBytes = send(serverSocket, buffer, strlen(buffer)+1, 0);
printf("send bytes: %d\n", sendBytes);
memset(buffer, 0, DATA_BUFSIZE);
recvBytes = recv(serverSocket, buffer, DATA_BUFSIZE, 0);
printf("recv bytes: %d\n", recvBytes);
printf("recv Message: %s\n", buffer);