【文件属性】:
文件名称:重叠IO模型之OverLapped完成例程模型WSACompletionRoutineServer VS2010
文件大小:7KB
文件格式:RAR
更新时间:2017-07-01 10:58:19
重叠IO模型 完成例程模型
重叠IO模型之OverLapped完成例程模型WSACompletionRoutineServer VS2010
基础入门 客户端与服务器端
客户端向服务器端发送数据
可接收多个客户端
#include
#include
#pragma comment (lib, "ws2_32.lib")
#define PORT 8088
#define MSG_SIZE 1024
SOCKET g_sConnect;
bool g_bConnect = false;
typedef struct
{
WSAOVERLAPPED overLap;
WSABUF wsaBuf;
char chMsg[MSG_SIZE];
DWORD nRecvNum;
DWORD nFlags;
SOCKET sClient;
}PRE_IO_OPERATION_DATA, *LP_PER_IO_OPERATION_DATA;
void CALLBACK CompletionRoutine(DWORD dwError,
DWORD dwTrans, LPWSAOVERLAPPED lpOverlap, DWORD nFlags);
DWORD WINAPI workThread(LPVOID lp)
{
LP_PER_IO_OPERATION_DATA lpData;
while(TRUE)
{
if (g_bConnect) // 有新的连接
{
// 为lpData分配空间并初始化
lpData = (LP_PER_IO_OPERATION_DATA)HeapAlloc(
GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PRE_IO_OPERATION_DATA));
lpData->wsaBuf.len = MSG_SIZE;
lpData->wsaBuf.buf = lpData->chMsg;
lpData->sClient = g_sConnect;
WSARecv(lpData->sClient, &lpData->wsaBuf,
1, &lpData->nRecvNum, &lpData->nFlags,
&lpData->overLap, CompletionRoutine);
g_bConnect = false; // 处理完毕
}
SleepEx(1000, TRUE);
}
return 0;
}
// 系统在WSARecv收到信息后,自动调用此函数,并传入参数--回调函数
void CALLBACK CompletionRoutine(DWORD dwError,
DWORD dwTrans, LPWSAOVERLAPPED lpOverlap, DWORD nFlags)
{
LP_PER_IO_OPERATION_DATA lpData = (LP_PER_IO_OPERATION_DATA)lpOverlap;
if (0 != dwError) // 接收失败
{
printf("Socket %d Close!\n", lpData->sClient);
closesocket(lpData->sClient);
HeapFree(GetProcessHeap(), 0, lpData);
}
else // 接收成功
{
lpData->chMsg[dwTrans] = '\0';
send(lpData->sClient, lpData->chMsg, dwTrans, 0);
printf("Socket:%d MSG: %s \n", lpData->sClient, lpData->chMsg);
memset(&lpData->overLap, 0, sizeof(WSAOVERLAPPED));
lpData->wsaBuf.len = MSG_SIZE;
lpData->wsaBuf.buf = lpData->chMsg;
// 继续接收来自客户端的数据 实现 WSARecv与CompletionRoutine循环
WSARecv(lpData->sClient, &lpData->wsaBuf,1, &lpData->nRecvNum,
&lpData->nFlags, &lpData->overLap, CompletionRoutine);
}
}
int main()
{
WSADATA wsaData;
WSAStartup(0x0202, &wsaData);
SOCKET sListen;
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in addrListen;
addrListen.sin_family = AF_INET;
addrListen.sin_port = htons(PORT);
addrListen.sin_addr.S_un.S_addr = htonl(ADDR_ANY);
int nErrorCode = 0;
nErrorCode = bind(sListen, (sockaddr*)&addrListen, sizeof(sockaddr));
nErrorCode = listen(sListen, 5);
DWORD nThreadID;
CreateThread(NULL, 0, workThread, NULL, 0, &nThreadID);
sockaddr_in addrConnect;
int nAddrLen = sizeof(sockaddr_in);
printf("Server Started!\n");
while(TRUE)
{
g_sConnect= accept(sListen, (sockaddr*)&addrConnect, &nAddrLen);
if (INVALID_SOCKET == g_sConnect)
{
return -1;
}
g_bConnect = true; // 连接成功
printf("Accept Client :%s -- PORT:%d\n",
inet_ntoa(addrConnect.sin_addr), htons(addrConnect.sin_port));
}
return 0;
}
【文件预览】:
WSACompletionRoutineClient
----WSACompletionRoutineClient.cpp(2KB)
----WSACompletionRoutineClient.vcxproj.filters(964B)
----WSACompletionRoutineClient.vcxproj.user(143B)
----WSACompletionRoutineClient.vcxproj(4KB)
WSACompletionRoutineServer
----WSACompletionRoutineServer.vcxproj(4KB)
----WSACompletionRoutineServer.vcxproj.user(143B)
----WSACompletionRoutineServer.cpp(3KB)
----WSACompletionRoutineServer.vcxproj.filters(964B)
WSACompletionRoutineServer.sln