Перейти к содержимому

Пример реализации модели портов завершения

Пример реализации модели портов завершения.

#include <iostream.h>
#include <Winsock2.h>
#pragma comment(lib, "ws2_32.lib")
 
 
void ErrorView();
DWORD WINAPI MainServThread(LPVOID CompletionPort);
 
SOCKET sock;
#define RECV 1001
#define SEND 1002
 
typedef struct
{
   OVERLAPPED Overlapped;
   WSABUF     DataBuf;
   CHAR       Buffer[1024];
   int        IO_Type;
 
} io_str, * lp_io_str;
 
typedef struct
{
   SOCKET Socket;
 
} io_handle_data, * lp_io_handle_data;
 
 
int main()
{
        WSADATA wsaData;
        
        if(!WSAStartup(0x0202,&wsaData))
        {
                HANDLE io_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
                if(io_port != NULL)
                {
                        SYSTEM_INFO SystemInfo;GetSystemInfo(&SystemInfo);
 
                        for(int i = 0; i < (int)SystemInfo.dwNumberOfProcessors ; i++)
                        {
                                HANDLE MainThread;
                                DWORD dwID;
                                if((MainThread = CreateThread(NULL,0,
                                                                 MainServThread,
                                                                                         (LPVOID)io_port,0,
                                                                                         &dwID)) == NULL)
                                {cout<<"Error CreateThread"<<endl;return -1;}
                                
                                CloseHandle(MainThread);
                        }
 
                        SOCKET sockList;
                        if((sockList = WSASocket(AF_INET,
                                                     SOCK_STREAM,0,
                                                                         NULL,0,
                                                                         WSA_FLAG_OVERLAPPED)) != INVALID_SOCKET)
                        {
                                SOCKADDR_IN InetAddr;
                                InetAddr.sin_family      = AF_INET;
                                InetAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
                                InetAddr.sin_port        = htons(4004);
                                                                
                                if(bind(sockList,(PSOCKADDR)&InetAddr,sizeof(InetAddr)) != SOCKET_ERROR)
                                {
                                        if(!(listen(sockList,SOMAXCONN)))
                                        {
                                                SOCKET Accept;
                                                while(TRUE)
                                                {
                                                        if ((Accept = WSAAccept(sockList,NULL,NULL,NULL,0)) != SOCKET_ERROR)
                                                        {
                                                                cout<<"Accept: "<<Accept<<endl;
                                                        
                                                                lp_io_handle_data sock;
 
                                                                sock = (lp_io_handle_data)GlobalAlloc(GPTR,sizeof(io_handle_data));
                                                                if(sock)
                                                                {
                                                                        sock->Socket = Accept;
 
                                                                        if(CreateIoCompletionPort((HANDLE)Accept,io_port,(DWORD)sock,0) != NULL)
                                                                        {
                                                                                lp_io_str io_data;
                                                                                
                                                                                if((io_data = (lp_io_str)GlobalAlloc(GPTR,sizeof(io_str))) != NULL)
                                                                                {
                                                                                        ZeroMemory(&(io_data->Overlapped),sizeof(OVERLAPPED));
                                                                                        io_data->DataBuf.len = 1024;
                                                                                        io_data->DataBuf.buf = io_data->Buffer;
                                                                                        io_data->IO_Type     = RECV;
 
                                                DWORD dwRecv,dwFlags = 0;
                                                                                        if(WSARecv(Accept,
                                                                                                       &(io_data->DataBuf),
                                                                                                           1,&dwRecv,
                                                                                                           &dwFlags,
                                                                                                           &(io_data->Overlapped),
                                                                                                           NULL) != SOCKET_ERROR)
                                                                                        {
                                                                                                cout<<"WSARecv..."<<endl;}
                                                                                        else
                                                                                        {if(WSAGetLastError() != ERROR_IO_PENDING)
                                                                                        {cout<<"Error WSARecv..."<<endl;ErrorView();return -1;}}
 
 
                                                                                }else{cout<<"Error GlobalAlloc(2)"<<endl;}
                                                                        }else{cout<<"Error CreateIoCompletionPort(2)"<<endl;}   
                                                                }else{cout<<"Error GlobalAlloc"<<endl;}
                                                        }else{cout<<"Error WSAAccept..."<<endl;ErrorView();return -1;}
                                                }//while(TRUE)
                                        }else{cout<<"Error listen..."<<endl;ErrorView();}
                                }else{cout<<"Error bind..."<<endl;ErrorView();}
                        }else{cout<<"Error WSASocket..."<<endl;ErrorView();}
                }else{cout<<"Error CreateIoCompletionPort..."<<endl;}
        }else{cout<<"Error WSAStartup..."<<endl;ErrorView();}
 
        WSACleanup();
 
        return 0;
}
 
/*************************************************************/
//Iioie ii?oa caaa?oaiey
/*************************************************************/
DWORD WINAPI MainServThread(LPVOID CompletionPort)
{
        HANDLE h_io_port = (HANDLE)CompletionPort;
        DWORD dwBytes;
        lp_io_str io_data;
        lp_io_handle_data sock;
 
 
        while(TRUE)
        {
                if(GetQueuedCompletionStatus(h_io_port,
                                                                        &dwBytes,
                                                                        (LPDWORD)&sock,
                                                                        (LPOVERLAPPED *)&io_data,
                                                                        INFINITE) == 0)
                {cout<<"Error...(1)"<<endl;}
 
                if(dwBytes == 0)
                {
                                if(closesocket(sock->Socket) != SOCKET_ERROR)
                                {cout<<"closesocket: "<<sock->Socket<<endl;}
                                else{cout<<"error closesocket..."<<endl;ErrorView();}
 
                                GlobalFree(io_data);
                                GlobalFree(sock);
                                continue;
                }
 
                if(io_data->IO_Type == SEND)
                {
                        cout<<"SEND: "<<io_data->Buffer<<endl;
                }
 
                                
                if(io_data->IO_Type == RECV)
                {
                         cout<<io_data->Buffer<<endl;
                         if(io_data->Buffer[0] == '0')
                         {
                        
                                 ZeroMemory(&(io_data->Overlapped),sizeof(OVERLAPPED));
                                 ZeroMemory(&(io_data->Buffer),sizeof(1024));
                             io_data->DataBuf.len = 1024;
 
                                 strcpy(io_data->Buffer,"ok");
                                 io_data->DataBuf.buf = io_data->Buffer;
                                 io_data->IO_Type     = SEND;
                                
                                 DWORD dwSend;
 
                                 if (WSASend(sock->Socket,
                                                 &(io_data->DataBuf),
                                                         1,&dwSend,0,
                                                         &(io_data->Overlapped),
                                                         NULL) == SOCKET_ERROR)
                                 {if(WSAGetLastError()!= ERROR_IO_PENDING)
                                 {cout<<"Error WSASend..."<<endl;ErrorView();return -1;}}
 
                                 continue;
                                        
 
                         }//if
 
                        
                }
 
                ZeroMemory(&(io_data->Overlapped),sizeof(OVERLAPPED));
                ZeroMemory(&(io_data->Buffer),sizeof(1024));
                io_data->DataBuf.len = 1024;
                io_data->DataBuf.buf = io_data->Buffer;
                io_data->IO_Type     = RECV;
                DWORD dwRecv,dwFlags = 0;
 
                if(WSARecv(sock->Socket,
                              &(io_data->DataBuf),1,
                                  &dwRecv,&dwFlags,
                                  &(io_data->Overlapped),
                                  NULL) == SOCKET_ERROR)
                {if(WSAGetLastError()!= ERROR_IO_PENDING)
                {cout<<"Error WSARecv..."<<endl;ErrorView();return -1;}}
                
                
        }
 
        return 0;
}
 
/*************************************************************/
//Ooieoey auaiaa ioeaie...
/*************************************************************/
void ErrorView()
{
        LPVOID lpMsgBuf = NULL;
        FormatMessage
        (FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,WSAGetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf, 0, NULL);
        CharToOem((LPTSTR)lpMsgBuf,(LPTSTR)lpMsgBuf);
        cout<<(LPCTSTR)lpMsgBuf<<endl;
        LocalFree(lpMsgBuf);
}

Метки: