Windows网络编程:Complete Routine的基本使用
Complete Routine的基本使用,下面是一个简单的例子
#include
<
winsock2.h
>
#include < stdio.h >
#pragma comment(lib, " ws2_32.lib " )
#define LISTEN_PORT 5080
#define BUFF_SIZE 256
void CALLBACK WorkerRoutine(DWORD error, DWORD bytes_transferred,
LPWSAOVERLAPPED overlapped,
DWORD inflags);
typedef struct
{
WSAOVERLAPPED overlapped;
DWORD recv_bytes;
SOCKET client_sock;
DWORD inflags;
WSABUF buff;
}SOCKINFO;
int main( void )
{
WSADATA wsaData;
int nRet;
SOCKET listen_sock;
SOCKADDR_IN listen_addr;
SOCKET client_sock;
SOCKADDR_IN client_addr;
int client_addr_len = sizeof (client_addr);
char buff[BUFF_SIZE];
DWORD recv_bytes = 0 ;
int index;
SOCKINFO sockInfo;
WSAEVENT wsaEvent;
nRet = WSAStartup(MAKEWORD( 2 , 2 ), & wsaData);
if ( 0 != nRet)
{
printf( " WSAStartup() failed, error:%d.\n " , WSAGetLastError());
return 1 ;
}
listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == listen_sock)
{
printf( " socket() failed, error:%d.\n " , WSAGetLastError());
goto retflag1;
}
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
listen_addr.sin_port = htons(LISTEN_PORT);
nRet = bind(listen_sock, (SOCKADDR * ) & listen_addr, sizeof (listen_addr));
if (nRet == SOCKET_ERROR)
{
printf( " bind() failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
goto retflag1;
}
nRet = listen(listen_sock, 5 );
if (SOCKET_ERROR == nRet)
{
printf( " listen() failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
goto retflag1;
}
client_sock = accept(listen_sock, (SOCKADDR * ) & client_addr, & client_addr_len);
if (INVALID_SOCKET == client_sock)
{
printf( " accept failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
goto retflag1;
}
sockInfo.inflags = 0 ;
memset( & sockInfo.overlapped, 0 , sizeof (sockInfo.overlapped));
sockInfo.client_sock = client_sock;
sockInfo.buff.buf = buff;
sockInfo.buff.len = BUFF_SIZE;
sockInfo.overlapped.hEvent = (HANDLE) & sockInfo;
if (WSARecv(client_sock, & sockInfo.buff, 1 , & sockInfo.recv_bytes, & sockInfo.inflags, & sockInfo.overlapped, WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() == WSA_IO_PENDING)
{
printf( " WSARecv() WSA_IO_PENDING.\n " );
}
else
{
printf( " WSARecv failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
closesocket(client_sock);
goto retflag1;
}
}
wsaEvent = WSACreateEvent();
if (WSA_INVALID_EVENT == wsaEvent)
{
printf( " WSACreateEvent() failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
closesocket(client_sock);
goto retflag1;
}
while ( 1 )
{
index = WSAWaitForMultipleEvents( 1 , & wsaEvent, FALSE, WSA_INFINITE, TRUE);
if (index = WAIT_IO_COMPLETION)
{
continue ;
}
else
{
printf( " WSAWaitForMultipleEvents() failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
closesocket(client_sock);
WSACloseEvent(wsaEvent);
goto retflag1;
}
}
closesocket(listen_sock);
closesocket(client_sock);
WSACloseEvent(wsaEvent);
retflag1:
nRet = WSACleanup();
if ( 0 != nRet)
{
printf( " WSACleanup() failed, error:%d.\n " , WSAGetLastError());
return 1 ;
}
return 0 ;
}
void CALLBACK WorkerRoutine(DWORD error, DWORD bytes_transferred,
LPWSAOVERLAPPED overlapped,
DWORD inflags)
{
SOCKINFO * sockInfo = NULL;
if (error != 0 )
{
printf( " Callback error:%d.\n " , error);
return ;
}
if (bytes_transferred == 0 )
{
printf( " peer closed.\n " );
return ;
}
sockInfo = (SOCKINFO * )overlapped -> hEvent;
printf( " %s " , sockInfo -> buff.buf);
sockInfo -> inflags = 0 ;
memset( & sockInfo -> overlapped, 0 , sizeof (sockInfo -> overlapped));
sockInfo -> overlapped.hEvent = (HANDLE)sockInfo;
if (WSARecv(sockInfo -> client_sock, & sockInfo -> buff, 1 , & sockInfo -> recv_bytes, & sockInfo -> inflags, & sockInfo -> overlapped, WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() == WSA_IO_PENDING)
{
printf( " WSARecv() WSA_IO_PENDING.\n " );
}
else
{
printf( " WSARecv failed, error:%d.\n " , WSAGetLastError());
return ;
}
}
}
#include < stdio.h >
#pragma comment(lib, " ws2_32.lib " )
#define LISTEN_PORT 5080
#define BUFF_SIZE 256
void CALLBACK WorkerRoutine(DWORD error, DWORD bytes_transferred,
LPWSAOVERLAPPED overlapped,
DWORD inflags);
typedef struct
{
WSAOVERLAPPED overlapped;
DWORD recv_bytes;
SOCKET client_sock;
DWORD inflags;
WSABUF buff;
}SOCKINFO;
int main( void )
{
WSADATA wsaData;
int nRet;
SOCKET listen_sock;
SOCKADDR_IN listen_addr;
SOCKET client_sock;
SOCKADDR_IN client_addr;
int client_addr_len = sizeof (client_addr);
char buff[BUFF_SIZE];
DWORD recv_bytes = 0 ;
int index;
SOCKINFO sockInfo;
WSAEVENT wsaEvent;
nRet = WSAStartup(MAKEWORD( 2 , 2 ), & wsaData);
if ( 0 != nRet)
{
printf( " WSAStartup() failed, error:%d.\n " , WSAGetLastError());
return 1 ;
}
listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == listen_sock)
{
printf( " socket() failed, error:%d.\n " , WSAGetLastError());
goto retflag1;
}
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
listen_addr.sin_port = htons(LISTEN_PORT);
nRet = bind(listen_sock, (SOCKADDR * ) & listen_addr, sizeof (listen_addr));
if (nRet == SOCKET_ERROR)
{
printf( " bind() failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
goto retflag1;
}
nRet = listen(listen_sock, 5 );
if (SOCKET_ERROR == nRet)
{
printf( " listen() failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
goto retflag1;
}
client_sock = accept(listen_sock, (SOCKADDR * ) & client_addr, & client_addr_len);
if (INVALID_SOCKET == client_sock)
{
printf( " accept failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
goto retflag1;
}
sockInfo.inflags = 0 ;
memset( & sockInfo.overlapped, 0 , sizeof (sockInfo.overlapped));
sockInfo.client_sock = client_sock;
sockInfo.buff.buf = buff;
sockInfo.buff.len = BUFF_SIZE;
sockInfo.overlapped.hEvent = (HANDLE) & sockInfo;
if (WSARecv(client_sock, & sockInfo.buff, 1 , & sockInfo.recv_bytes, & sockInfo.inflags, & sockInfo.overlapped, WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() == WSA_IO_PENDING)
{
printf( " WSARecv() WSA_IO_PENDING.\n " );
}
else
{
printf( " WSARecv failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
closesocket(client_sock);
goto retflag1;
}
}
wsaEvent = WSACreateEvent();
if (WSA_INVALID_EVENT == wsaEvent)
{
printf( " WSACreateEvent() failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
closesocket(client_sock);
goto retflag1;
}
while ( 1 )
{
index = WSAWaitForMultipleEvents( 1 , & wsaEvent, FALSE, WSA_INFINITE, TRUE);
if (index = WAIT_IO_COMPLETION)
{
continue ;
}
else
{
printf( " WSAWaitForMultipleEvents() failed, error:%d.\n " , WSAGetLastError());
closesocket(listen_sock);
closesocket(client_sock);
WSACloseEvent(wsaEvent);
goto retflag1;
}
}
closesocket(listen_sock);
closesocket(client_sock);
WSACloseEvent(wsaEvent);
retflag1:
nRet = WSACleanup();
if ( 0 != nRet)
{
printf( " WSACleanup() failed, error:%d.\n " , WSAGetLastError());
return 1 ;
}
return 0 ;
}
void CALLBACK WorkerRoutine(DWORD error, DWORD bytes_transferred,
LPWSAOVERLAPPED overlapped,
DWORD inflags)
{
SOCKINFO * sockInfo = NULL;
if (error != 0 )
{
printf( " Callback error:%d.\n " , error);
return ;
}
if (bytes_transferred == 0 )
{
printf( " peer closed.\n " );
return ;
}
sockInfo = (SOCKINFO * )overlapped -> hEvent;
printf( " %s " , sockInfo -> buff.buf);
sockInfo -> inflags = 0 ;
memset( & sockInfo -> overlapped, 0 , sizeof (sockInfo -> overlapped));
sockInfo -> overlapped.hEvent = (HANDLE)sockInfo;
if (WSARecv(sockInfo -> client_sock, & sockInfo -> buff, 1 , & sockInfo -> recv_bytes, & sockInfo -> inflags, & sockInfo -> overlapped, WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() == WSA_IO_PENDING)
{
printf( " WSARecv() WSA_IO_PENDING.\n " );
}
else
{
printf( " WSARecv failed, error:%d.\n " , WSAGetLastError());
return ;
}
}
}