procedure TAlarmTCPServer.Close; begin Self.Terminate; shutdown(FServerSocket,FD_CLOSE); closesocket(FServerSocket); WSACleanup(); end;
constructor TAlarmTCPServer.Create(AParent: TThreadPool;CompletePort:THandle;AlarmPort:Integer;ASubDataLs: TThreadList;ATimeOutCounter:TTimeOutCounter); var wsaData: TWSADATA ; Ret:Integer; begin FreeOnTerminate := True; FTimeOutCounter := ATimeOutCounter; FThreadPool := AParent; FAlarmCompletePort := CompletePort; FAlarmPort := AlarmPort; FAlarmSocketLists := ASubDataLs; //初始化侦听网络 Ret := WSAStartup($0202, wsaData); if Ret <> 0 then begin FThreadPool.PShowRealMsg(0,'报警TCP服务','初始化网络失败!'); Self.Terminate; Exit; end; inherited Create(False); end;
destructor TAlarmTCPServer.Destroy; begin inherited; end;
procedure TAlarmTCPServer.Execute; var Ret:Integer; InternetAddr: SOCKADDR_IN; Accept:TSocket; PHandleData:LPPerHandelData; Flags,RecvBytes:DWORD; TimeOutObject : TCounterObject; nRecvBuf,nSendBuf:integer; Block : pBlock; i:Integer; begin //创建TCPServer的侦听Socket FServerSocket := WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, WSA_FLAG_OVERLAPPED); if (FServerSocket = INVALID_SOCKET) then begin FThreadPool.PShowRealMsg(0,'报警TCP服务','报警TCPSocket创建失败!'); Self.Terminate; exit; end; //绑定侦听地址和端口 InternetAddr.sin_family := AF_INET; InternetAddr.sin_addr.s_addr := htonl(INADDR_ANY); InternetAddr.sin_port := htons(FAlarmPort); if (bind(FServerSocket, InternetAddr, sizeof(InternetAddr)) = SOCKET_ERROR) then begin FThreadPool.PShowRealMsg(0,'报警TCP服务','报警TCP绑定地址和侦听端口失败!'); Self.Terminate; exit; end; //启动服务Socket的侦听 if (listen(FServerSocket, 5) = SOCKET_ERROR) then begin FThreadPool.PShowRealMsg(0,'报警TCP服务','报警TCP服务器侦听启动失败!'); Self.Terminate; exit; end; FThreadPool.PShowRealMsg(0,'报警TCP服务','报警TCP服务器侦听线程启动成功!');
//接收客户Socket接入,并放入队列 while( not Self.Terminated ) DO begin //侦听报警控制端口,接收新客户端Socket的接入 try Accept := WSAAccept(FServerSocket, nil, nil, nil, 0); except end;
if (Accept = SOCKET_ERROR) then begin FThreadPool.PShowRealMsg(0,'报警TCP服务','客户端Socket连接失败!'); Continue; end else begin FThreadPool.PShowRealMsg(0,'报警TCP服务','客户端【Socket='+ IntToStr(Accept) +'】接入成功,等待验证!'); end;
//创建接入的Socket对应结构体,并与完成端口关联 PHandleData := LPPerHandelData(GlobalAlloc(GPTR, sizeof(PerHandelData))); if (PHandleData = nil) then begin shutdown(Accept,FD_CLOSE); closesocket(Accept); Continue; end;
//与完成端口关联 PHandleData.Socket := Accept; if (CreateIoCompletionPort(Accept, FAlarmCompletePort, DWORD(PHandleData), 0) = 0) then begin shutdown(Accept,FD_CLOSE); closesocket(Accept); GlobalFree(DWORD(PHandleData)); Continue; end;
function TAlarmTCPServer.PrepareRecv(PHandelData:LPPerHandelData; Block: PBlock): Boolean; var ErrCode: Integer; Flags, Transfer: Cardinal; begin if not Assigned(Block) then Block := PHandelData.MemoryBuffer.AllocBlock ; with Block^.Data do begin Flags := 0; OperType := APP_OPERTYPE_RECV; FillChar(Buffer, SizeOf(Buffer), 0); FillChar(Overlapped, SizeOf(Overlapped), 0); wsaBuffer.buf := @Buffer; wsaBuffer.len := DATABUF_MAXSIZE; Result := SOCKET_ERROR <> WSARecv(PHandelData.Socket, @wsaBuffer, 1, @Transfer, @Flags, @Overlapped, nil); if not Result then begin ErrCode := WSAGetLastError; Result := ErrCode = ERROR_IO_PENDING; if not Result then begin Block.Data.IsUse := False; end; end; end; end;