Open GoogleCodeExporter opened 8 years ago
At Iocp.TcpSocket.Pas, the TIocpTcpSocket.Listen function may cause resource leak, when WSASocket or bind or Iocp.Winsock2.listen or AssociateSocketWithCompletionPort return is failed. May Change as: function TIocpTcpSocket.Listen(const Host: string; Port: Word; InitAcceptNum: Integer): Boolean; const IPV6_V6ONLY = 27; var PHost: PWideChar; ListenSocket: TSocket; InAddrInfo: TAddrInfoW; POutAddrInfo, Ptr: PAddrInfoW; ListenCount: Integer; LastErr: Integer; SocketList:TList<TSocket>; begin Result := False; if not Assigned(FAcceptThread) then Exit; try // 如果传递了一个有效地址则监听该地址 // 否则监听所有本地地址 if (Host = '') then PHost := nil else PHost := PWideChar(Host); FillChar(InAddrInfo, SizeOf(TAddrInfoW), 0); InAddrInfo.ai_flags := AI_PASSIVE; InAddrInfo.ai_family := AF_UNSPEC; InAddrInfo.ai_socktype := SOCK_STREAM; InAddrInfo.ai_protocol := IPPROTO_TCP; if (getaddrinfo(PHost, PWideChar(IntToStr(Port)), @InAddrInfo, @POutAddrInfo) <> 0) then begin LastErr := WSAGetLastError; AppendLog('%s.Listen.getaddrinfo, ERROR %d=%s', [ClassName, LastErr, SysErrorMessage(LastErr)], ltWarning); Exit; end; SocketList:=TList<TSocket>.Create; try try {$region '检查监听个数是否已达上限'} Ptr := POutAddrInfo; ListenCount := FAcceptThread.ListenCount; while (Ptr <> nil) do begin Inc(ListenCount); Ptr := Ptr.ai_next; end; if (ListenCount > FAcceptThread.MAX_LISTEN_SOCKETS) then Exit; {$endregion} Ptr := POutAddrInfo; while (Ptr <> nil) do begin ListenSocket := WSASocket(Ptr.ai_family, Ptr.ai_socktype, Ptr.ai_protocol, nil, 0, WSA_FLAG_OVERLAPPED); if (ListenSocket = INVALID_SOCKET) then Exit; // no := 0; // setsockopt(ListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, PAnsiChar(@no), sizeof(no)); if (bind(ListenSocket, Ptr.ai_addr, Ptr.ai_addrlen) = SOCKET_ERROR) then begin LastErr := WSAGetLastError; Iocp.Winsock2.closesocket(ListenSocket); AppendLog('%s.Listen.bind(Port=%d, Socket=%d), ERROR %d=%s', [ClassName, Port, ListenSocket, LastErr, SysErrorMessage(LastErr)], ltWarning); Exit; end; if (Iocp.Winsock2.listen(ListenSocket, SOMAXCONN) = SOCKET_ERROR) then begin LastErr := WSAGetLastError; Iocp.Winsock2.closesocket(ListenSocket); AppendLog('%s.Listen.listen(Port=%d, Socket=%d), ERROR %d=%s', [ClassName, Port, ListenSocket, LastErr, SysErrorMessage(LastErr)], ltWarning); Exit; end; if not AssociateSocketWithCompletionPort(ListenSocket, nil) then begin Iocp.Winsock2.closesocket(ListenSocket); AppendLog('%s.Listen.AssociateSocketWithCompletionPort(Port=%d, Socket=%d) failed', [ClassName, Port, ListenSocket], ltWarning); Exit; end; if not FAcceptThread.NewListen(ListenSocket, Ptr.ai_family, InitAcceptNum) then begin Iocp.Winsock2.closesocket(ListenSocket); Exit; end; SocketList.Add(ListenSocket); Ptr := Ptr.ai_next; end; finally freeaddrinfo(POutAddrInfo); end; Result := True; except on e: Exception do begin for i:=0 to SocketList.Count-1 do begin FAcceptThread.StopListen(SocketList[i]); end; AppendLog('%s.Listen ERROR %s=%s', [ClassName, e.ClassName, e.Message], ltException); end; end; finally SocketList.Free; end; end;
Original issue reported on code.google.com by Hezihang...@gmail.com on 5 Jul 2013 at 4:45
Hezihang...@gmail.com
Original issue reported on code.google.com by
Hezihang...@gmail.com
on 5 Jul 2013 at 4:45