Windows IO模型 2 通过历程完成 服务器

#include   "stdafx.h"
#include   <winsock2.h>
#include   <iostream>
#pragma   comment (   lib ,   "ws2_32.lib"   )

using   namespace     std ;

#define       MSGSIZE   1024
SOCKET        g_sNewClientConnection ;
BOOL          g_bNewConnectionArrived   =   FALSE ;

struct   PER_IO_OPERATION_DATA
{
        WSAOVERLAPPED   overlap   ;                 //   重叠结构体
        WSABUF           Buffer ;                  //   缓冲对象
        char             szMessage [   MSGSIZE ];      //   缓冲区字符对象

        DWORD            NumberOfBytesRecvd ;      //   接受字节位
        DWORD            Flags ;                   //   标识位
        SOCKET           sClient ;                 // Socket
};

typedef   PER_IO_OPERATION_DATA *   LPPER_IO_OPERATION_DATA   ;

enum
{
        MAIN_RETURN_ERROR            =  -1,
        MAIN_RETURN_NORMAL           =   0,
};

void   CALLBACK   CompletionROUTINE (   DWORD   dwError ,   DWORD   cbTransferred   ,   LPWSAOVERLAPPED   lpOverlapped ,   DWORD   dwFlags   )
{
        LPPER_IO_OPERATION_DATA   lpPerIOData   = (   LPPER_IO_OPERATION_DATA   ) lpOverlapped ;

        if (   dwError   != 0 ||   cbTransferred   == 0 )
     {
             closesocket (   lpPerIOData   -> sClient   );
             HeapFree (   GetProcessHeap   (), 0,   lpPerIOData   );
     }
        else
     {
             lpPerIOData -> szMessage   [ cbTransferred ] =   '\0' ;
             //   向客户端发送数据
             send (   lpPerIOData   -> sClient ,   lpPerIOData   -> szMessage ,   cbTransferred , 0 );
             memset ( & lpPerIOData   -> overlap , 0,   sizeof   ( WSAOVERLAPPED ) );

             lpPerIOData -> Buffer   . len   =   MSGSIZE ;
             lpPerIOData -> Buffer   . buf   =   lpPerIOData   -> szMessage ;
             WSARecv (   lpPerIOData   -> sClient , & lpPerIOData   -> Buffer , 1, & lpPerIOData   -> NumberOfBytesRecvd ,
              &   lpPerIOData -> Flags   , & lpPerIOData ->   overlap ,   CompletionROUTINE   );

             cout << lpPerIOData   -> Buffer .   buf << endl   ;
     }
}


DWORD   WINAPI   WorkThread (   LPVOID   lpParam   )
{
        LPPER_IO_OPERATION_DATA   lpPerIOData   =   NULL ;
        while (   TRUE   )
     {
             if (   g_bNewConnectionArrived     //   如果有新的请求
          {
                 lpPerIOData   = ( LPPER_IO_OPERATION_DATA   ) HeapAlloc (   GetProcessHeap (),   HEAP_ZERO_MEMORY   ,   sizeof (   PER_IO_OPERATION_DATA   ) );

                 lpPerIOData -> Buffer   . len   =   MSGSIZE ;
                 lpPerIOData -> Buffer   . buf   =   lpPerIOData   -> szMessage ;
                 lpPerIOData -> sClient       =   g_sNewClientConnection   ;

                 WSARecv (   lpPerIOData   -> sClient , & lpPerIOData   -> Buffer , 1, & lpPerIOData   -> NumberOfBytesRecvd ,
                       &   lpPerIOData -> Flags   ,   & lpPerIOData   -> overlap ,   CompletionROUTINE   );
                 g_bNewConnectionArrived   =   FALSE ;

                 cout << lpPerIOData   -> Buffer .   buf << endl   ;

          }

             SleepEx ( 1000,   TRUE   );
     }

        return   0;
}

int   _tmain (   int   argc   ,   _TCHAR *   argv [])
{
        //   初始化 Winsock 2.2
        WSADATA   wsaData   ;
        if (   WSAStartup   (   MAKEWORD ( 2, 2 ), &   wsaData   ) != 0 )
     {
             cout << "WSAStartup   无法初始化   !"   << endl   ;
             return   MAIN_RETURN_ERROR   ;
     }

        SOCKET   ListenSocket   ;
        ListenSocket   =   WSASocket   (   AF_INET ,   SOCK_STREAM , 0,   NULL , 0,   WSA_FLAG_OVERLAPPED   );
        if (   INVALID_SOCKET   ==   ListenSocket   )
     {
             cout << "Socket Failed !"   << " Reson:" <<   WSAGetLastError   ()<< endl   ;
             WSACleanup ();
             return   MAIN_RETURN_ERROR   ;
     }

        //   设置服务器 Socket   地址
        SOCKADDR_IN   addrServ   ;
        addrServ . sin_family      =   AF_INET ;
        addrServ . sin_port        =   htons ( 9990 );     //   服务器端口号
        addrServ . sin_addr   . S_un .   S_addr   =   htonl   (   INADDR_ANY   );

        //   绑定
        int       retVal   ;
        retVal   =   bind   (   ListenSocket , (   const   struct   sockaddr   *)& addrServ   ,   sizeof (   SOCKADDR_IN   ) );
        if (   SOCKET_ERROR   ==   retVal   )
     {
             cout << "bind failed !"   << "   Reson: " <<   WSAGetLastError   ()<< endl   ;
             closesocket (   ListenSocket   );
             WSACleanup ();
             return   -1;
     }

        //   监听
        retVal   =   listen   (   ListenSocket , 3 );
        if (   SOCKET_ERROR   ==   retVal   )
     {
             cout << "listen failed !"   << " Reson:" <<   WSAGetLastError   ()<< endl   ;
             closesocket (   ListenSocket   );
             WSACleanup ();
             return   -1;
     }

        DWORD   dwThreadId   ;
        CreateThread (   NULL   , 0,   WorkThread ,   NULL , 0, & dwThreadId   );

        //   循环接受客户端请求
        sockaddr_in   addrClient   ;
        int   addrClientLen   =   sizeof (   addrClient   );
        while (   TRUE   )
     {
             g_sNewClientConnection     =   accept (   ListenSocket , ( struct   sockaddr   *)&   addrClient , & addrClientLen   );
             g_bNewConnectionArrived   =   TRUE ;
             cout << "Accept Client: " <<   inet_ntoa ( addrClient   . sin_addr )<<   " : " <<   ntohs ( addrClient   . sin_port )<<   endl ;
     }

        closesocket ( ListenSocket   );
        closesocket ( g_sNewClientConnection   );
        system ( "pause"   );
        return   0;
}
  







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值