配合上一篇WSAEventSelect模型的Server使用,測試效果用。做了些修改,修改為多線程實作IO業務處理。
// g_wsaEventSelect_Client.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Winsock2.h>
#include <malloc.h>
#pragma comment(lib,"Ws2_32.lib")
SOCKET g_socketServer = INVALID_SOCKET;
WSAEVENT g_wsaEvent = WSA_INVALID_EVENT;
// 初始化socket
void InitSock()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
/* Confirm that the WinSock DLL supports 2.2. */
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return;
}
}
void UnInitSock()
{
if (g_wsaEvent != WSA_INVALID_EVENT)
{
WSACloseEvent(g_wsaEvent);
}
if (g_socketServer != INVALID_SOCKET)
{
closesocket(g_socketServer);
}
WSACleanup();
}
struct ST_THREAD_PARAM
{
SOCKET socket;
WSAEVENT wsaEvent;
};
DWORD WINAPI ServiceThread(LPVOID lpThreadParameter)
{
ST_THREAD_PARAM* pThread = (ST_THREAD_PARAM*)lpThreadParameter;
SOCKET socketServer = pThread->socket;
WSAEVENT wsaEvent = pThread->wsaEvent;
printf("新線程%d起動/n",GetCurrentThreadId());
while(true)
{
int nRet=::WSAWaitForMultipleEvents(1,&wsaEvent,FALSE,10000,FALSE);
if(nRet==WAIT_FAILED) // 失敗
{
printf("failed WSAWaitForMultipleEvents/n");
break;
}
else if(nRet==WSA_WAIT_TIMEOUT) // 逾時
{
printf(" WSA_WAIT_TIMEOUT ... /n");
continue;
}
else // 成功 -- 網絡事件發生
{
WSANETWORKEVENTS wsaNetEvent;
::WSAEnumNetworkEvents(socketServer,wsaEvent,&wsaNetEvent);
if(wsaNetEvent.lNetworkEvents&FD_READ)
{
printf("FD_READ event occurs.../n");
char buffer[1024];
int nRet = recv(socketServer,buffer,1024,0);
if (nRet>0)
{
buffer[nRet] = '/0';
printf("收到資料 %s/n",buffer);
Sleep(3000);
printf("發送資料..../n");
int nSend = send(socketServer,buffer,nRet,0);
}
else
{
UnInitSock();
printf("線程%d退出/n",GetCurrentThreadId());
return -1;
}
}
else if(wsaNetEvent.lNetworkEvents&FD_WRITE)
{
printf("FD_WRITE event occurs.../n");
printf("發送資料..../n");
char szBuffer[] = "Hello world...";
int nLen = sizeof(szBuffer);
nRet = send(socketServer,szBuffer,nLen,0);
if (nRet == SOCKET_ERROR)
{
printf("send() error .../n");
UnInitSock();
printf("線程%d退出/n",GetCurrentThreadId());
return -1;
}
printf("nRet of send() is %d/n",nRet);
}
if(wsaNetEvent.lNetworkEvents&FD_CLOSE)
{
printf("FD_CLOSE event occurs.../n");
int nErrorCode = WSAGetLastError();
printf("Error code is %d/n",nErrorCode);
if (nErrorCode == WSAECONNRESET)
{
printf("WSAECONNRESET error./n");
}
else if (nErrorCode == WSAENETDOWN)
{
printf("WSAENETDOWN error./n");
}
else if (nErrorCode == WSAENETRESET)
{
printf("WSAENETRESET error./n");
}
UnInitSock();
printf("線程%d退出/n",GetCurrentThreadId());
return -1;
}
}
}
printf("線程%d退出/n",GetCurrentThreadId());
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
InitSock();
g_socketServer=socket(AF_INET,SOCK_STREAM,0);
if (g_socketServer == INVALID_SOCKET)
{
UnInitSock();
return -1;
}
sockaddr_in sin;
sin.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
sin.sin_family=AF_INET;
sin.sin_port=htons(3456);
if (connect(g_socketServer,(sockaddr*)&sin,sizeof(sockaddr)) == SOCKET_ERROR)
{
UnInitSock();
return -1;
}
g_wsaEvent=::WSACreateEvent();
::WSAEventSelect(g_socketServer,g_wsaEvent,FD_READ|FD_WRITE|FD_CLOSE);
ST_THREAD_PARAM* pThreadParam = new ST_THREAD_PARAM();
pThreadParam->socket = g_socketServer;
pThreadParam->wsaEvent = g_wsaEvent;
HANDLE hThread = ::CreateThread(NULL,0,ServiceThread,(LPVOID)pThreadParam,0,NULL);
if (hThread == INVALID_HANDLE_VALUE)
{
printf("Failed to create new thread.../n");
UnInitSock();
return -1;
}
printf("WaitForSingleObject(hThread,INFINITE) waiting.../n");
WaitForSingleObject(hThread,INFINITE);
printf("WaitForSingleObject(hThread,INFINITE) return .../n");
delete pThreadParam;
//while(true)
//{
// int nRet=::WSAWaitForMultipleEvents(1,&g_wsaEvent,FALSE,10000,FALSE);
// if(nRet==WAIT_FAILED) // 失敗
// {
// printf("failed wait for single object/n");
// break;
// }
// else if(nRet==WSA_WAIT_TIMEOUT) // 逾時
// {
// printf(" WSA_WAIT_TIMEOUT ... /n");
// continue;
// }
// else // 成功 -- 網絡事件發生
// {
// WSANETWORKEVENTS wsaNetEvent;
// ::WSAEnumNetworkEvents(g_socketServer,g_wsaEvent,&wsaNetEvent);
// if(wsaNetEvent.lNetworkEvents&FD_READ)
// {
// printf("FD_READ event occurs.../n");
// char buffer[1024];
// int nRet = recv(g_socketServer,buffer,1024,0);
// if (nRet>0)
// {
// buffer[nRet] = '/0';
// printf("收到資料 %s/n",buffer);
// Sleep(3000);
// printf("發送資料..../n");
// int nSend = send(g_socketServer,buffer,nRet,0);
// }
// else
// {
// UnInitSock();
// return -1;
// }
//
// }
// else if(wsaNetEvent.lNetworkEvents&FD_WRITE)
// {
// printf("FD_WRITE event occurs.../n");
// printf("發送資料..../n");
// char szBuffer[] = "Hello world...";
// int nLen = sizeof(szBuffer);
// nRet = send(g_socketServer,szBuffer,nLen,0);
// if (nRet == SOCKET_ERROR)
// {
// printf("send() error .../n");
// UnInitSock();
// return -1;
// }
// printf("nRet of send() is %d/n",nRet);
// }
// if(wsaNetEvent.lNetworkEvents&FD_CLOSE)
// {
// printf("FD_CLOSE event occurs.../n");
// int nErrorCode = WSAGetLastError();
// printf("Error code is %d/n",nErrorCode);
// if (nErrorCode == WSAECONNRESET)
// {
// printf("WSAECONNRESET error./n");
// }
// else if (nErrorCode == WSAENETDOWN)
// {
// printf("WSAENETDOWN error./n");
// }
// else if (nErrorCode == WSAENETRESET)
// {
// printf("WSAENETRESET error./n");
// }
// UnInitSock();
// return -1;
// }
// }
//}
return 0;
}
/*
* Windows Sockets definitions of regular Berkeley error constants
#define WSAEWOULDBLOCK (WSABASEERR+35)
#define WSAEINPROGRESS (WSABASEERR+36)
#define WSAEALREADY (WSABASEERR+37)
#define WSAENOTSOCK (WSABASEERR+38)
#define WSAEDESTADDRREQ (WSABASEERR+39)
#define WSAEMSGSIZE (WSABASEERR+40)
#define WSAEPROTOTYPE (WSABASEERR+41)
#define WSAENOPROTOOPT (WSABASEERR+42)
#define WSAEPROTONOSUPPORT (WSABASEERR+43)
#define WSAESOCKTNOSUPPORT (WSABASEERR+44)
#define WSAEOPNOTSUPP (WSABASEERR+45)
#define WSAEPFNOSUPPORT (WSABASEERR+46)
#define WSAEAFNOSUPPORT (WSABASEERR+47)
#define WSAEADDRINUSE (WSABASEERR+48)
#define WSAEADDRNOTAVAIL (WSABASEERR+49)
#define WSAENETDOWN (WSABASEERR+50)
#define WSAENETUNREACH (WSABASEERR+51)
#define WSAENETRESET (WSABASEERR+52)
#define WSAECONNABORTED (WSABASEERR+53)
#define WSAECONNRESET (WSABASEERR+54)
#define WSAENOBUFS (WSABASEERR+55)
#define WSAEISCONN (WSABASEERR+56)
#define WSAENOTCONN (WSABASEERR+57)
#define WSAESHUTDOWN (WSABASEERR+58)
#define WSAETOOMANYREFS (WSABASEERR+59)
#define WSAETIMEDOUT (WSABASEERR+60)
#define WSAECONNREFUSED (WSABASEERR+61)
#define WSAELOOP (WSABASEERR+62)
#define WSAENAMETOOLONG (WSABASEERR+63)
#define WSAEHOSTDOWN (WSABASEERR+64)
#define WSAEHOSTUNREACH (WSABASEERR+65)
#define WSAENOTEMPTY (WSABASEERR+66)
#define WSAEPROCLIM (WSABASEERR+67)
#define WSAEUSERS (WSABASEERR+68)
#define WSAEDQUOT (WSABASEERR+69)
#define WSAESTALE (WSABASEERR+70)
#define WSAEREMOTE (WSABASEERR+71)
*/