- //---------------------------------------------------------------------------
- #include <vcl.h>
- #pragma hdrstop
- #include "thrListen.h"
- #include "Unit1.h"
- #pragma package(smart_init)
- #pragma comment(lib,"ws2_32.lib")
- //---------------------------------------------------------------------------
- __fastcall TListenThread::TListenThread(bool CreateSuspended)
- : TThread(CreateSuspended)
- {
- }
- //---------------------------------------------------------------------------
- void __fastcall TListenThread::Execute()
- {
- //---- Place thread code here ----
- SYSTEM_INFO si ;
- Integer i ;
- HANDLE hThread ;
- DWORD ThreadID ;
- SOCKET AConnect ;
- sockaddr_in addr ;
- Integer len ;
- DWORD BytesRecv, Flags;
- PPER_OPERATION_DATA pPerIoDat ;
- // FCompletPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, 0,0,0 );
- if((FCompletPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0))==NULL)
- {
- MessageBox(0, "CreateIoCompletionPort failed.", "Error", MB_OK +
- MB_ICONINFORMATION);
- return;
- }
- GetSystemInfo( &si );
- for ( i=0 ;i<si.dwNumberOfProcessors;i++ )
- {
- // hThread = CreateThread( NULL,0,&WorkerThread,(void *)(FCompletPort),0,ThreadID );
- if
- (
- ( hThread=CreateThread(NULL,0,WorkerThread,FCompletPort,0,&ThreadID) )
- == NULL
- )
- {
- MessageBox(0, "CreateThread() failed with error.", "Error", MB_OK +
- MB_ICONINFORMATION);
- return;
- }
- CloseHandle( hThread );
- }
- if ( !InitSocket() )
- return;
- while ( !this->Terminated )
- {
- YPER_HANDLE_DATA * PerHandleData = NULL;
- len = sizeof(addr);
- AConnect = accept( FListenSock, (SOCKADDR*)&addr, &len );
- if ( AConnect == INVALID_SOCKET )
- {
- SleepEx( 110, false );
- continue;
- }
- PerHandleData=(PPER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(YPER_HANDLE_DATA));
- PerHandleData->Sock = AConnect;
- memcpy(&PerHandleData->ClientAddr, &addr, len);
- // 将接受套接字和完成端口关联起来
- CreateIoCompletionPort(
- (HANDLE)AConnect,
- FCompletPort,
- (DWORD)PerHandleData,
- 0
- );
- // CreateIoCompletionPort( (HANDLE)AConnect, FCompletPort, AConnect, 0 );
- pPerIoDat = NULL;
- pPerIoDat = (PPER_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(YPER_OPERATION_DATA));
- memset( &(pPerIoDat->Overlap), sizeof(OVERLAPPED), 0 );
- memset( pPerIoDat->Buf, BUFFER_SIZE, 0 );
- pPerIoDat->BufData.len = BUFFER_SIZE;
- pPerIoDat->BufData.buf = pPerIoDat->Buf;
- pPerIoDat->OprtType = RECV_POSTED;
- Flags = 0;
- // WSARecv( AConnect, &(pPerIoDat->BufData), 1, BytesRecv, Flags,
- // &(pPerIoDat->Overlap), NULL );
- WSARecv(
- PerHandleData->Sock,
- &(pPerIoDat->BufData),
- 1,
- &BytesRecv,
- &Flags,
- (LPWSAOVERLAPPED)&(pPerIoDat->Overlap),
- NULL
- );
- }
- PostQueuedCompletionStatus( FCompletPort, 0,0,NULL );
- CloseHandle( FCompletPort );
- }
- //---------------------------------------------------------------------------
- BOOL __fastcall TListenThread::InitSocket(void)
- {
- sockaddr_in addr;
- bool result = False;
- FListenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
- if ( FListenSock == INVALID_SOCKET )
- {
- MessageBox(0, "Call socket() failed.", "Error", MB_OK +
- MB_ICONSTOP);
- return result;
- }
- addr.sin_family = AF_INET;
- addr.sin_port = htons(LISTEN_PORT);
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- if ( bind( FListenSock, (const sockaddr *)&addr, sizeof(SOCKADDR) ) == SOCKET_ERROR )
- {
- MessageBox(0, "Call bind failed.", "Error", MB_OK +
- MB_ICONSTOP);
- return result;
- }
- if ( listen( FListenSock, 5 ) == SOCKET_ERROR )
- {
- MessageBox(0, "Call listen failed.", "Error", MB_OK +
- MB_ICONSTOP);
- return result;
- }
- result = True;
- return result;
- }
- //---------------------------------------------------------------------------
- DWORD WINAPI WorkerThread(LPVOID CompletPortID)
- {
- HANDLE CompletPort ;
- DWORD CompletKey,BytesTransd,BytesSend,BytesRecv,Flags ;
- PPER_OPERATION_DATA pPerIoDat = NULL;
- PPER_HANDLE_DATA PerHandleData = NULL;
- // LPPER_IO_DATA PerIoData = NULL;
- CompletPort = HANDLE(CompletPortID);
- while (1)
- {
- BytesTransd=0;CompletKey=0;
- GetQueuedCompletionStatus
- (
- CompletPort,
- &BytesTransd,
- (PULONG_PTR)&PerHandleData,
- (LPOVERLAPPED*)(&pPerIoDat),
- /*550*/INFINITE
- );
- if ( ( BytesTransd == 0 ) &
- ( (pPerIoDat==NULL ) || (pPerIoDat->OprtType == RECV_POSTED) ||(pPerIoDat->OprtType == SEND_POSTED) )
- )
- {
- closesocket( CompletKey );
- GlobalFree(PerHandleData);
- GlobalFree(pPerIoDat);
- continue;
- }
- // 数据处理
- // 这儿就收到了来自客户端的数据
- if ( pPerIoDat->OprtType == RECV_POSTED )
- {
- frmMain->ListBox1->Items->Add( pPerIoDat->BufData.buf );
- }
- Flags = 0;
- // 为下一个重叠调用建立单I/O操作数据
- memset( &pPerIoDat->Overlap, sizeof(OVERLAPPED), 0 );
- memset( pPerIoDat->Buf, 4096, 0 );
- pPerIoDat->BufData.len = 4096;
- pPerIoDat->BufData.buf = pPerIoDat->Buf;
- pPerIoDat->OprtType = RECV_POSTED;
- WSARecv( CompletKey, &(pPerIoDat->BufData), 1, &BytesRecv, &Flags,
- (LPWSAOVERLAPPED)&(pPerIoDat->Overlap), NULL );
- }
- //closesocket( CompletKey );
- //Dispose( pPerIoDat );
- }
- //---------------------------------------------------------------------------
socket IOCP
最新推荐文章于 2025-06-04 13:52:46 发布