Windows IO模型 2 通过历程完成 服务器
2013-12-20 13:58
309 查看
#include "stdafx.h"
[align=left]#include <winsock2.h>[/align]
[align=left]#include <iostream>[/align]
[align=left]#pragma comment( lib, "ws2_32.lib" )[/align]
[align=left]
[/align]
[align=left]using namespace std;[/align]
[align=left]
[/align]
[align=left]#define MSGSIZE 1024[/align]
[align=left]SOCKET g_sNewClientConnection;[/align]
[align=left]BOOL g_bNewConnectionArrived = FALSE;[/align]
[align=left]
[/align]
[align=left]struct PER_IO_OPERATION_DATA[/align]
[align=left]{[/align]
[align=left] WSAOVERLAPPED overlap ; // 重叠结构体[/align]
[align=left] WSABUF Buffer; // 缓冲对象[/align]
[align=left] char szMessage[ MSGSIZE]; // 缓冲区字符对象[/align]
[align=left]
[/align]
[align=left] DWORD NumberOfBytesRecvd; // 接受字节位[/align]
[align=left] DWORD Flags; // 标识位[/align]
SOCKET sClient; //
Socket
[align=left]};[/align]
[align=left]
[/align]
[align=left]typedef PER_IO_OPERATION_DATA* LPPER_IO_OPERATION_DATA ;[/align]
[align=left]
[/align]
[align=left]enum[/align]
[align=left]{[/align]
MAIN_RETURN_ERROR
= -1,
MAIN_RETURN_NORMAL
= 0,
[align=left]};[/align]
[align=left]
[/align]
[align=left]void CALLBACK CompletionROUTINE( DWORD dwError, DWORD cbTransferred , LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags )[/align]
[align=left]{[/align]
LPPER_IO_OPERATION_DATA lpPerIOData =
( LPPER_IO_OPERATION_DATA )lpOverlapped;
[align=left]
[/align]
if( dwError !=
0 || cbTransferred ==
0 )
[align=left] {[/align]
[align=left] closesocket( lpPerIOData ->sClient );[/align]
HeapFree( GetProcessHeap (),
0, lpPerIOData );
[align=left] }[/align]
[align=left] else[/align]
[align=left] {[/align]
lpPerIOData->szMessage [cbTransferred]
= '\0';
[align=left] // 向客户端发送数据[/align]
send( lpPerIOData ->sClient, lpPerIOData ->szMessage, cbTransferred,
0 );
memset(
&lpPerIOData ->overlap,
0, sizeof (WSAOVERLAPPED)
);
[align=left]
[/align]
[align=left] lpPerIOData->Buffer .len = MSGSIZE;[/align]
[align=left] lpPerIOData->Buffer .buf = lpPerIOData ->szMessage;[/align]
WSARecv( lpPerIOData ->sClient,
&lpPerIOData ->Buffer,
1, &lpPerIOData ->NumberOfBytesRecvd,
& lpPerIOData->Flags ,
&lpPerIOData-> overlap, CompletionROUTINE );
[align=left]
[/align]
[align=left] cout<<lpPerIOData ->Buffer. buf<<endl ;[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]DWORD WINAPI WorkThread( LPVOID lpParam )[/align]
[align=left]{[/align]
[align=left] LPPER_IO_OPERATION_DATA lpPerIOData = NULL;[/align]
[align=left] while( TRUE )[/align]
[align=left] {[/align]
[align=left] if( g_bNewConnectionArrived ) // 如果有新的请求[/align]
[align=left] {[/align]
lpPerIOData =
(LPPER_IO_OPERATION_DATA )HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY , sizeof( PER_IO_OPERATION_DATA )
);
[align=left]
[/align]
[align=left] lpPerIOData->Buffer .len = MSGSIZE;[/align]
[align=left] lpPerIOData->Buffer .buf = lpPerIOData ->szMessage;[/align]
lpPerIOData->sClient
= g_sNewClientConnection ;
[align=left]
[/align]
WSARecv( lpPerIOData ->sClient,
&lpPerIOData ->Buffer,
1, &lpPerIOData ->NumberOfBytesRecvd,
& lpPerIOData->Flags ,
&lpPerIOData ->overlap, CompletionROUTINE );
[align=left] g_bNewConnectionArrived = FALSE;[/align]
[align=left]
[/align]
[align=left] cout<<lpPerIOData ->Buffer. buf<<endl ;[/align]
[align=left]
[/align]
[align=left] }[/align]
[align=left]
[/align]
SleepEx(
1000, TRUE );
[align=left] }[/align]
[align=left]
[/align]
[align=left] return 0;[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]int _tmain( int argc , _TCHAR* argv[])[/align]
[align=left]{[/align]
// 初始化Winsock
2.2
[align=left] WSADATA wsaData ;[/align]
if( WSAStartup ( MAKEWORD(
2, 2 ), & wsaData )
!= 0 )
[align=left] {[/align]
[align=left] cout<<"WSAStartup 无法初始化 !" <<endl ;[/align]
[align=left] return MAIN_RETURN_ERROR ;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] SOCKET ListenSocket ;[/align]
ListenSocket = WSASocket ( AF_INET, SOCK_STREAM,
0, NULL,
0, WSA_FLAG_OVERLAPPED );
[align=left] if( INVALID_SOCKET == ListenSocket )[/align]
[align=left] {[/align]
cout<<"Socket
Failed !" <<"
Reson:"<< WSAGetLastError ()<<endl ;
[align=left] WSACleanup();[/align]
[align=left] return MAIN_RETURN_ERROR ;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] // 设置服务器Socket 地址[/align]
[align=left] SOCKADDR_IN addrServ ;[/align]
addrServ.sin_family
= AF_INET;
addrServ.sin_port
= htons(
9990 ); // 服务器端口号
[align=left] addrServ.sin_addr .S_un. S_addr = htonl ( INADDR_ANY );[/align]
[align=left]
[/align]
[align=left] // 绑定[/align]
[align=left] int retVal ;[/align]
retVal = bind ( ListenSocket,
( const struct sockaddr *)&addrServ , sizeof( SOCKADDR_IN )
);
[align=left] if( SOCKET_ERROR == retVal )[/align]
[align=left] {[/align]
cout<<"bind
failed !" <<"
Reson: "<< WSAGetLastError ()<<endl ;
[align=left] closesocket( ListenSocket );[/align]
[align=left] WSACleanup();[/align]
[align=left] return -1;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] // 监听[/align]
retVal = listen ( ListenSocket,
3 );
[align=left] if( SOCKET_ERROR == retVal )[/align]
[align=left] {[/align]
cout<<"listen
failed !" <<"
Reson:"<< WSAGetLastError ()<<endl ;
[align=left] closesocket( ListenSocket );[/align]
[align=left] WSACleanup();[/align]
[align=left] return -1;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] DWORD dwThreadId ;[/align]
CreateThread( NULL ,
0, WorkThread, NULL,
0, &dwThreadId );
[align=left]
[/align]
[align=left] // 循环接受客户端请求[/align]
[align=left] sockaddr_in addrClient ;[/align]
[align=left] int addrClientLen = sizeof( addrClient );[/align]
[align=left] while( TRUE )[/align]
[align=left] {[/align]
g_sNewClientConnection
= accept( ListenSocket,
(struct sockaddr *)& addrClient,
&addrClientLen );
[align=left] g_bNewConnectionArrived = TRUE;[/align]
cout<<"Accept
Client: "<< inet_ntoa(addrClient .sin_addr)<< "
: "<< ntohs(addrClient .sin_port)<< endl;
[align=left] }[/align]
[align=left]
[/align]
[align=left] closesocket(ListenSocket );[/align]
[align=left] closesocket(g_sNewClientConnection );[/align]
[align=left] system("pause" );[/align]
[align=left] return 0;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]#include <winsock2.h>[/align]
[align=left]#include <iostream>[/align]
[align=left]#pragma comment( lib, "ws2_32.lib" )[/align]
[align=left]
[/align]
[align=left]using namespace std;[/align]
[align=left]
[/align]
[align=left]#define MSGSIZE 1024[/align]
[align=left]SOCKET g_sNewClientConnection;[/align]
[align=left]BOOL g_bNewConnectionArrived = FALSE;[/align]
[align=left]
[/align]
[align=left]struct PER_IO_OPERATION_DATA[/align]
[align=left]{[/align]
[align=left] WSAOVERLAPPED overlap ; // 重叠结构体[/align]
[align=left] WSABUF Buffer; // 缓冲对象[/align]
[align=left] char szMessage[ MSGSIZE]; // 缓冲区字符对象[/align]
[align=left]
[/align]
[align=left] DWORD NumberOfBytesRecvd; // 接受字节位[/align]
[align=left] DWORD Flags; // 标识位[/align]
SOCKET sClient; //
Socket
[align=left]};[/align]
[align=left]
[/align]
[align=left]typedef PER_IO_OPERATION_DATA* LPPER_IO_OPERATION_DATA ;[/align]
[align=left]
[/align]
[align=left]enum[/align]
[align=left]{[/align]
MAIN_RETURN_ERROR
= -1,
MAIN_RETURN_NORMAL
= 0,
[align=left]};[/align]
[align=left]
[/align]
[align=left]void CALLBACK CompletionROUTINE( DWORD dwError, DWORD cbTransferred , LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags )[/align]
[align=left]{[/align]
LPPER_IO_OPERATION_DATA lpPerIOData =
( LPPER_IO_OPERATION_DATA )lpOverlapped;
[align=left]
[/align]
if( dwError !=
0 || cbTransferred ==
0 )
[align=left] {[/align]
[align=left] closesocket( lpPerIOData ->sClient );[/align]
HeapFree( GetProcessHeap (),
0, lpPerIOData );
[align=left] }[/align]
[align=left] else[/align]
[align=left] {[/align]
lpPerIOData->szMessage [cbTransferred]
= '\0';
[align=left] // 向客户端发送数据[/align]
send( lpPerIOData ->sClient, lpPerIOData ->szMessage, cbTransferred,
0 );
memset(
&lpPerIOData ->overlap,
0, sizeof (WSAOVERLAPPED)
);
[align=left]
[/align]
[align=left] lpPerIOData->Buffer .len = MSGSIZE;[/align]
[align=left] lpPerIOData->Buffer .buf = lpPerIOData ->szMessage;[/align]
WSARecv( lpPerIOData ->sClient,
&lpPerIOData ->Buffer,
1, &lpPerIOData ->NumberOfBytesRecvd,
& lpPerIOData->Flags ,
&lpPerIOData-> overlap, CompletionROUTINE );
[align=left]
[/align]
[align=left] cout<<lpPerIOData ->Buffer. buf<<endl ;[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]DWORD WINAPI WorkThread( LPVOID lpParam )[/align]
[align=left]{[/align]
[align=left] LPPER_IO_OPERATION_DATA lpPerIOData = NULL;[/align]
[align=left] while( TRUE )[/align]
[align=left] {[/align]
[align=left] if( g_bNewConnectionArrived ) // 如果有新的请求[/align]
[align=left] {[/align]
lpPerIOData =
(LPPER_IO_OPERATION_DATA )HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY , sizeof( PER_IO_OPERATION_DATA )
);
[align=left]
[/align]
[align=left] lpPerIOData->Buffer .len = MSGSIZE;[/align]
[align=left] lpPerIOData->Buffer .buf = lpPerIOData ->szMessage;[/align]
lpPerIOData->sClient
= g_sNewClientConnection ;
[align=left]
[/align]
WSARecv( lpPerIOData ->sClient,
&lpPerIOData ->Buffer,
1, &lpPerIOData ->NumberOfBytesRecvd,
& lpPerIOData->Flags ,
&lpPerIOData ->overlap, CompletionROUTINE );
[align=left] g_bNewConnectionArrived = FALSE;[/align]
[align=left]
[/align]
[align=left] cout<<lpPerIOData ->Buffer. buf<<endl ;[/align]
[align=left]
[/align]
[align=left] }[/align]
[align=left]
[/align]
SleepEx(
1000, TRUE );
[align=left] }[/align]
[align=left]
[/align]
[align=left] return 0;[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]int _tmain( int argc , _TCHAR* argv[])[/align]
[align=left]{[/align]
// 初始化Winsock
2.2
[align=left] WSADATA wsaData ;[/align]
if( WSAStartup ( MAKEWORD(
2, 2 ), & wsaData )
!= 0 )
[align=left] {[/align]
[align=left] cout<<"WSAStartup 无法初始化 !" <<endl ;[/align]
[align=left] return MAIN_RETURN_ERROR ;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] SOCKET ListenSocket ;[/align]
ListenSocket = WSASocket ( AF_INET, SOCK_STREAM,
0, NULL,
0, WSA_FLAG_OVERLAPPED );
[align=left] if( INVALID_SOCKET == ListenSocket )[/align]
[align=left] {[/align]
cout<<"Socket
Failed !" <<"
Reson:"<< WSAGetLastError ()<<endl ;
[align=left] WSACleanup();[/align]
[align=left] return MAIN_RETURN_ERROR ;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] // 设置服务器Socket 地址[/align]
[align=left] SOCKADDR_IN addrServ ;[/align]
addrServ.sin_family
= AF_INET;
addrServ.sin_port
= htons(
9990 ); // 服务器端口号
[align=left] addrServ.sin_addr .S_un. S_addr = htonl ( INADDR_ANY );[/align]
[align=left]
[/align]
[align=left] // 绑定[/align]
[align=left] int retVal ;[/align]
retVal = bind ( ListenSocket,
( const struct sockaddr *)&addrServ , sizeof( SOCKADDR_IN )
);
[align=left] if( SOCKET_ERROR == retVal )[/align]
[align=left] {[/align]
cout<<"bind
failed !" <<"
Reson: "<< WSAGetLastError ()<<endl ;
[align=left] closesocket( ListenSocket );[/align]
[align=left] WSACleanup();[/align]
[align=left] return -1;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] // 监听[/align]
retVal = listen ( ListenSocket,
3 );
[align=left] if( SOCKET_ERROR == retVal )[/align]
[align=left] {[/align]
cout<<"listen
failed !" <<"
Reson:"<< WSAGetLastError ()<<endl ;
[align=left] closesocket( ListenSocket );[/align]
[align=left] WSACleanup();[/align]
[align=left] return -1;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] DWORD dwThreadId ;[/align]
CreateThread( NULL ,
0, WorkThread, NULL,
0, &dwThreadId );
[align=left]
[/align]
[align=left] // 循环接受客户端请求[/align]
[align=left] sockaddr_in addrClient ;[/align]
[align=left] int addrClientLen = sizeof( addrClient );[/align]
[align=left] while( TRUE )[/align]
[align=left] {[/align]
g_sNewClientConnection
= accept( ListenSocket,
(struct sockaddr *)& addrClient,
&addrClientLen );
[align=left] g_bNewConnectionArrived = TRUE;[/align]
cout<<"Accept
Client: "<< inet_ntoa(addrClient .sin_addr)<< "
: "<< ntohs(addrClient .sin_port)<< endl;
[align=left] }[/align]
[align=left]
[/align]
[align=left] closesocket(ListenSocket );[/align]
[align=left] closesocket(g_sNewClientConnection );[/align]
[align=left] system("pause" );[/align]
[align=left] return 0;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
相关文章推荐
- Windows五个网络IO模型(服务器用)
- Windows平台下 IO模型 服务器
- 可伸缩的IO完成端口服务器模型(IOCP)
- 可伸缩的IO完成端口服务器模型(IOCP)(中文版)
- 可伸缩的IO完成端口服务器模型(IOCP)(英文版)
- Windows Socket IO 模型【转帖】
- 通过quartz定时任务完成对FTP服务器上文档的下载
- Linux 服务器IO模型 epoll
- windows系统上利用putty通过SSH连接亚马逊AWS服务器
- 阿里云服务器上安装完成并启动Tomcat后,通过http不能访问--解决办法
- 服务器IO模型之Select
- gitolite 通过测试服务器发布代码到正式服务器一步完成
- C/S通信---服务器IO多路复用模型之poll的使用
- 阻塞IO服务器模型之单线程服务器模型
- windows下通过vnc访问liunx服务器
- 非阻塞IO服务器模型
- Windows下性能最好的I/O模型——完成端口
- 唯快不破:高性能网络服务器5--IO复用与并发模型
- 一个链接引发的血案---------服务器 IO及网络流量暴涨解决历程
- 夺命雷公狗---linux NO:30 linux之通过X-Shell在windows上传文件到服务器上