- 浏览: 30862 次
- 性别:
- 来自: 杭州
最新评论
配合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) */
发表评论
-
使用WinINet和WinHTTP实现Http访问
2011-08-22 19:23 5084Http访问有两种方式,GET和POST,就编程来说GET方式 ... -
PHP Socket实例
2011-08-22 00:16 1118下面是一段php socket编程的例子,当然也可以使用fso ... -
windows网络通信之IO模型
2011-08-21 21:35 1236《Socket I/O模型全接触》 作 者: flyinw ... -
socket函数说明
2011-08-21 21:23 893accept(接受socket连线) ... -
Socket 通讯的概念性过程
2011-08-21 21:21 9781.SOCKET 通讯TCP方式一般流程图 服务端 ...
相关推荐
练习套接字编程,写的使用WSAEventClient I/O模式的 客户端,MFC 单文档,多线程。 WSAEventSelect更适合服务器,写成客户端用来练习。 VC++ 6.0 编译。
WSAEventSelect模型基础 客户端向服务器发送消息 VS2010 C
WSAEventSelect模型
VC编程模型示例之 WSAEventSelect 模型 配套讲解请参考我的blog http://blog.csdn.net/PiggyXP
本来想不要积分的,但是没得办法,这里最低选择2分
用WSAEventSelect结合线程池实现的服务器示例.希望能够帮助到那些热爱网络,但又迷失方向的朋友.
编写Win32程序模拟实现基于WSAEventSelect模型的两台计算机之间的通信,要求编程实现服务器端与客户端之间双向数据传递。客户端向服务器端发送“请输出从1到1000内所有的水仙花数”,服务器回应客户端给出结果。...
Winsock模型之WSAEventSelect(事件通知)
http://blog.csdn.net/wangjieest/article/details/7042108 http://blog.csdn.net/ithzhang/article/details/8476556
基于WSAEventSelect模型,,使用线程池技术,可以处理大量的客户I/O请求,程序定义SOCKET_BOJ THREAD_OBJ两个结构,通过链表记录对象。
是对WSAEventSelect模型的基本实现,可以研究学习下该模型的基本运行原理
Winsock WSAEventSelect 服务端模型源码
wsaEventSelect实现p2p的文件传输
详细介绍了事件网络模型相关的API,富有详细的说明文档,深刻的对模型的易错点讲解,附上了详细的实现的流程图
包括Windows网络编程套接字I/O模型中的select模型,WSAEventSelect模型,重叠模型,完成端口模型完整代码。因为Windows 网络编程这本书上提供的代码并不完全正确,所以花了3天,写了几个例子。其中也包括了一些C++编程的...
Winsock WSAEventSelect 服务端模型源码
详解WSAEventSelect网络模型-附件资源
采用C++语言编写,在VS2010下开发,可以直接运行,代码中有相关的注释。