/packages/fcl-net/src/ssockets.pp

https://github.com/slibre/freepascal · Puppet · 737 lines · 612 code · 125 blank · 0 comment · 15 complexity · 0024a81d6fb9045a3affd86daf8d3da4 MD5 · raw file

  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$MODE objfpc}{$H+}
  11. unit ssockets;
  12. interface
  13. uses
  14. SysUtils, Classes, ctypes, sockets;
  15. type
  16. TSocketErrorType = (
  17. seHostNotFound,
  18. seCreationFailed,
  19. seBindFailed,
  20. seListenFailed,
  21. seConnectFailed,
  22. seAcceptFailed,
  23. seAcceptWouldBlock);
  24. TSocketOption = (soDebug,soReuseAddr,soKeepAlive,soDontRoute,soBroadcast,
  25. soOOBinline);
  26. TSocketOptions = Set of TSocketOption;
  27. ESocketError = class(Exception)
  28. Code: TSocketErrorType;
  29. constructor Create(ACode: TSocketErrorType; const MsgArgs: array of const);
  30. end;
  31. { TSocketStream }
  32. TSocketStream = class(THandleStream)
  33. Private
  34. FReadFlags: Integer;
  35. FSocketInitialized : Boolean;
  36. FSocketOptions : TSocketOptions;
  37. FLastError : integer;
  38. FWriteFlags: Integer;
  39. Procedure GetSockOptions;
  40. Procedure SetSocketOptions(Value : TSocketOptions);
  41. function GetLocalAddress: TSockAddr;
  42. function GetRemoteAddress: TSockAddr;
  43. Public
  44. Constructor Create (AHandle : Longint);virtual;
  45. destructor Destroy; override;
  46. function Seek(Offset: Longint; Origin: Word): Longint; override;
  47. Function Read (Var Buffer; Count : Longint) : longint; Override;
  48. Function Write (Const Buffer; Count : Longint) :Longint; Override;
  49. Property SocketOptions : TSocketOptions Read FSocketOptions
  50. Write SetSocketOptions;
  51. property LocalAddress: TSockAddr read GetLocalAddress;
  52. property RemoteAddress: TSockAddr read GetRemoteAddress;
  53. Property LastError : Integer Read FLastError;
  54. Property ReadFlags : Integer Read FReadFlags Write FReadFlags;
  55. Property WriteFlags : Integer Read FWriteFlags Write FWriteFlags;
  56. end;
  57. TConnectEvent = Procedure (Sender : TObject; Data : TSocketStream) Of Object;
  58. TConnectQuery = Procedure (Sender : TObject; ASocket : Longint; Var Allow : Boolean) of Object;
  59. { TSocketServer }
  60. TSocketServer = Class(TObject)
  61. Private
  62. FOnIdle : TNotifyEvent;
  63. FNonBlocking : Boolean;
  64. FSocket : longint;
  65. FListened : Boolean;
  66. FAccepting : Boolean;
  67. FMaxConnections : Longint;
  68. FQueueSize : Longint;
  69. FOnConnect : TConnectEvent;
  70. FOnConnectQuery : TConnectQuery;
  71. Procedure DoOnIdle;
  72. Function GetReuseAddress: Boolean;
  73. Function GetKeepAlive : Boolean;
  74. Function GetLinger : Integer;
  75. Procedure SetReuseAddress (AValue : Boolean);
  76. Procedure SetKeepAlive (AValue : Boolean);
  77. Procedure SetLinger(ALinger : Integer);
  78. Protected
  79. FSockType : Longint;
  80. FBound : Boolean;
  81. Procedure DoConnect(ASocket : TSocketStream); Virtual;
  82. Function DoConnectQuery(ASocket : longint): Boolean ;Virtual;
  83. Procedure Bind; Virtual; Abstract;
  84. Function Accept: Longint;Virtual;Abstract;
  85. Function SockToStream (ASocket : Longint) : TSocketStream;Virtual;Abstract;
  86. Procedure Close; Virtual;
  87. function GetConnection: TSocketStream;
  88. Public
  89. Constructor Create(ASocket : Longint);
  90. Destructor Destroy; Override;
  91. Procedure Listen;
  92. function GetSockopt(ALevel,AOptName : cint; var optval; Var optlen : tsocklen): Boolean;
  93. function SetSockopt(ALevel,AOptName : cint; var optval; optlen : tsocklen): Boolean;
  94. Procedure StartAccepting;
  95. Procedure StopAccepting;
  96. Procedure SetNonBlocking;
  97. Property Bound : Boolean Read FBound;
  98. Property MaxConnections : longint Read FMaxConnections Write FMaxConnections;
  99. Property QueueSize : Longint Read FQueueSize Write FQueueSize default 5;
  100. Property OnConnect : TConnectEvent Read FOnConnect Write FOnConnect;
  101. Property OnConnectQuery : TConnectQuery Read FOnConnectQuery Write FOnConnectQuery;
  102. Property OnIdle : TNotifyEvent Read FOnIdle Write FOnIdle;
  103. Property NonBlocking : Boolean Read FNonBlocking;
  104. Property Socket : Longint Read FSocket;
  105. Property SockType : Longint Read FSockType;
  106. Property KeepAlive : Boolean Read GetKeepAlive Write SetKeepAlive;
  107. Property ReuseAddress : Boolean Read GetReuseAddress Write SetReuseAddress;
  108. // -1 means no linger. Any value >=0 sets linger on.
  109. Property Linger: Integer Read GetLinger Write Setlinger;
  110. end;
  111. { TInetServer }
  112. TInetServer = Class(TSocketServer)
  113. Protected
  114. FAddr : TINetSockAddr;
  115. FPort : Word;
  116. FHost: string;
  117. Function SockToStream (ASocket : Longint) : TSocketStream;Override;
  118. Function Accept : Longint;override;
  119. Public
  120. Procedure Bind; Override;
  121. Constructor Create(APort: Word);
  122. Constructor Create(const aHost: string; const APort: Word);
  123. Property Port : Word Read FPort;
  124. Property Host : string Read FHost;
  125. end;
  126. {$ifdef Unix}
  127. { TUnixServer }
  128. TUnixServer = Class(TSocketServer)
  129. Private
  130. FUnixAddr : TUnixSockAddr;
  131. FFileName : String;
  132. Protected
  133. Procedure Bind; Override;
  134. Function Accept : Longint;override;
  135. Function SockToStream (ASocket : Longint) : TSocketStream;Override;
  136. Procedure Close; override;
  137. Public
  138. Constructor Create(AFileName : String);
  139. Property FileName : String Read FFileName;
  140. end;
  141. {$endif}
  142. { TInetSocket }
  143. TInetSocket = Class(TSocketStream)
  144. Private
  145. FHost : String;
  146. FPort : Word;
  147. Protected
  148. Procedure DoConnect(ASocket : longint); Virtual;
  149. Public
  150. Constructor Create(ASocket : longint); Override; Overload;
  151. Constructor Create(const AHost: String; APort: Word); Overload;
  152. Property Host : String Read FHost;
  153. Property Port : Word Read FPort;
  154. end;
  155. {$ifdef Unix}
  156. TUnixSocket = Class(TSocketStream)
  157. Private
  158. FFileName : String;
  159. Protected
  160. Procedure DoConnect(ASocket : longint); Virtual;
  161. Public
  162. Constructor Create(ASocket : Longint); Overload;
  163. Constructor Create(AFileName : String); Overload;
  164. Property FileName : String Read FFileName;
  165. end;
  166. {$endif}
  167. Implementation
  168. uses
  169. {$ifdef unix}
  170. BaseUnix, Unix,
  171. {$endif}
  172. resolve;
  173. Const
  174. SocketWouldBlock = -2;
  175. { ---------------------------------------------------------------------
  176. ESocketError
  177. ---------------------------------------------------------------------}
  178. resourcestring
  179. strHostNotFound = 'Host name resolution for "%s" failed.';
  180. strSocketCreationFailed = 'Creation of socket failed: %s';
  181. strSocketBindFailed = 'Binding of socket failed: %s';
  182. strSocketListenFailed = 'Listening on port #%d failed, error: %d';
  183. strSocketConnectFailed = 'Connect to %s failed.';
  184. strSocketAcceptFailed = 'Could not accept a client connection on socket: %d, error %d';
  185. strSocketAcceptWouldBlock = 'Accept would block on socket: %d';
  186. constructor ESocketError.Create(ACode: TSocketErrorType; const MsgArgs: array of const);
  187. var
  188. s: String;
  189. begin
  190. Code := ACode;
  191. case ACode of
  192. seHostNotFound : s := strHostNotFound;
  193. seCreationFailed: s := strSocketCreationFailed;
  194. seBindFailed : s := strSocketBindFailed;
  195. seListenFailed : s := strSocketListenFailed;
  196. seConnectFailed : s := strSocketConnectFailed;
  197. seAcceptFailed : s := strSocketAcceptFailed;
  198. seAcceptWouldBLock : S:= strSocketAcceptWouldBlock;
  199. end;
  200. s := Format(s, MsgArgs);
  201. inherited Create(s);
  202. end;
  203. { ---------------------------------------------------------------------
  204. TSocketStream
  205. ---------------------------------------------------------------------}
  206. Constructor TSocketStream.Create (AHandle : Longint);
  207. begin
  208. Inherited Create(AHandle);
  209. FSocketInitialized := true;
  210. GetSockOptions;
  211. end;
  212. destructor TSocketStream.Destroy;
  213. begin
  214. if FSocketInitialized then
  215. {$ifdef netware}
  216. CloseSocket(Handle);
  217. {$else}
  218. FileClose(Handle);
  219. {$endif}
  220. inherited Destroy;
  221. end;
  222. Procedure TSocketStream.GetSockOptions;
  223. begin
  224. end;
  225. Procedure TSocketStream.SetSocketOptions(Value : TSocketOptions);
  226. begin
  227. end;
  228. Function TSocketStream.Seek(Offset: Longint; Origin: Word): Longint;
  229. begin
  230. Result:=0;
  231. end;
  232. Function TSocketStream.Read (Var Buffer; Count : Longint) : longint;
  233. Var
  234. Flags : longint;
  235. begin
  236. Flags:=FReadFlags;
  237. Result:=fprecv(handle,@Buffer,count,flags);
  238. If Result<0 then
  239. FLastError:=SocketError
  240. else
  241. FLastError:=0;
  242. end;
  243. Function TSocketStream.Write (Const Buffer; Count : Longint) :Longint;
  244. Var
  245. Flags : longint;
  246. begin
  247. Flags:=FWriteFlags;
  248. Result:=fpsend(handle,@Buffer,count,flags);
  249. If Result<0 then
  250. FLastError:=SocketError
  251. else
  252. FlastError:=0;
  253. end;
  254. function TSocketStream.GetLocalAddress: TSockAddr;
  255. var
  256. len: LongInt;
  257. begin
  258. len := SizeOf(TSockAddr);
  259. if fpGetSockName(Handle, @Result, @len) <> 0 then
  260. FillChar(Result, SizeOf(Result), 0);
  261. end;
  262. function TSocketStream.GetRemoteAddress: TSockAddr;
  263. var
  264. len: LongInt;
  265. begin
  266. len := SizeOf(TSockAddr);
  267. if fpGetPeerName(Handle, @Result, @len) <> 0 then
  268. FillChar(Result, SizeOf(Result), 0);
  269. end;
  270. { ---------------------------------------------------------------------
  271. TSocketServer
  272. ---------------------------------------------------------------------}
  273. Constructor TSocketServer.Create(ASocket : Longint);
  274. begin
  275. FSocket:=ASocket;
  276. FQueueSize :=5;
  277. FMaxConnections:=-1;
  278. end;
  279. Destructor TSocketServer.Destroy;
  280. begin
  281. Close;
  282. Inherited;
  283. end;
  284. Procedure TSocketServer.Close;
  285. begin
  286. If FSocket<>-1 Then
  287. {$ifdef netware}
  288. CloseSocket(FSocket);
  289. {$else}
  290. FileClose(FSocket);
  291. {$endif}
  292. FSocket:=-1;
  293. end;
  294. Procedure TSocketServer.Listen;
  295. begin
  296. If Not FBound then
  297. Bind;
  298. If Sockets.FpListen(FSocket,FQueueSize)<>0 then
  299. Raise ESocketError.Create(seListenFailed,[FSocket,SocketError]);
  300. end;
  301. function TSocketServer.GetSockopt(ALevel, AOptName: cint; Var optval;
  302. var optlen: tsocklen): Boolean;
  303. begin
  304. Result:=fpGetSockOpt(FSocket,ALevel,AOptName,@optval,@optlen)<>-1;
  305. end;
  306. function TSocketServer.SetSockopt(ALevel, AOptName: cint; var optval;
  307. optlen: tsocklen): Boolean;
  308. begin
  309. Result:=fpSetSockOpt(FSocket,ALevel,AOptName,@optval,optlen)<>-1;
  310. end;
  311. Function TSocketServer.GetConnection : TSocketStream;
  312. var
  313. NewSocket : longint;
  314. begin
  315. Result:=Nil;
  316. NewSocket:=Accept;
  317. If NewSocket>=0 then
  318. begin
  319. If FAccepting and DoConnectQuery(NewSocket) Then
  320. Result:=SockToStream(NewSocket)
  321. else
  322. CloseSocket(NewSocket);
  323. end
  324. end;
  325. Procedure TSocketServer.StartAccepting;
  326. Var
  327. NoConnections : Integer;
  328. Stream : TSocketStream;
  329. begin
  330. FAccepting := True;
  331. NoConnections := 0;
  332. Listen;
  333. Repeat
  334. Repeat
  335. Try
  336. Stream:=GetConnection;
  337. if Assigned(Stream) then
  338. begin
  339. Inc (NoConnections);
  340. DoConnect(Stream);
  341. end;
  342. except
  343. On E : ESocketError do
  344. begin
  345. If E.Code=seAcceptWouldBlock then
  346. DoOnIdle
  347. else
  348. Raise;
  349. end;
  350. end;
  351. Until (Stream<>Nil) or (Not NonBlocking);
  352. Until Not (FAccepting) or ((FMaxConnections<>-1) and (NoConnections>=FMaxConnections));
  353. end;
  354. Procedure TSocketServer.StopAccepting;
  355. begin
  356. FAccepting:=False;
  357. end;
  358. Procedure TSocketServer.DoOnIdle;
  359. begin
  360. If Assigned(FOnIdle) then
  361. FOnIdle(Self);
  362. end;
  363. function TSocketServer.GetReuseAddress: Boolean;
  364. Var
  365. L : cint;
  366. ls : Tsocklen;
  367. begin
  368. L:=0;
  369. ls:=0;
  370. {$IFDEF UNIX}
  371. if not GetSockOpt(SOL_SOCKET, SO_REUSEADDR, L, LS) then
  372. Raise ESocketError.CreateFmt('Failed to get SO_REUSEADDR to %d: %d',[l,socketerror]);
  373. Result:=(L<>0);
  374. {$ELSE}
  375. Result:=True;
  376. {$ENDIF}
  377. end;
  378. function TSocketServer.GetKeepAlive: Boolean;
  379. Var
  380. L : cint;
  381. ls : Tsocklen;
  382. begin
  383. L:=0;
  384. ls:=0;
  385. {$IFDEF UNIX}
  386. if Not GetSockOpt(SOL_SOCKET, SO_KEEPALIVE, L, LS) then
  387. Raise ESocketError.CreateFmt('Failed to get SO_KEEPALIVE: %d',[socketerror]);
  388. Result:=(L<>0);
  389. {$ELSE}
  390. Result:=True;
  391. {$ENDIF}
  392. end;
  393. function TSocketServer.GetLinger: Integer;
  394. Var
  395. L : linger;
  396. ls : tsocklen;
  397. begin
  398. L.l_onoff:=0;
  399. l.l_linger:=0;
  400. if Not GetSockOpt(SOL_SOCKET, SO_LINGER, l, ls) then
  401. Raise ESocketError.CreateFmt('Failed to set linger: %d',[socketerror]);
  402. if l.l_onoff=0 then
  403. Result:=-1
  404. else
  405. Result:=l.l_linger;
  406. end;
  407. Procedure TSocketServer.DoConnect(ASocket : TSocketStream);
  408. begin
  409. If Assigned(FOnConnect) Then
  410. FOnConnect(Self,ASocket);
  411. end;
  412. Function TSocketServer.DoConnectQuery(ASocket : Longint) : Boolean;
  413. begin
  414. Result:=True;
  415. If Assigned(FOnConnectQuery) then
  416. FOnConnectQuery(Self,ASocket,Result);
  417. end;
  418. Procedure TSocketServer.SetNonBlocking;
  419. begin
  420. {$ifdef Unix}
  421. fpfcntl(FSocket,F_SETFL,O_NONBLOCK);
  422. {$endif}
  423. FNonBlocking:=True;
  424. end;
  425. procedure TSocketServer.SetLinger(ALinger: Integer);
  426. Var
  427. L : linger;
  428. begin
  429. L.l_onoff:=Ord(ALinger>0);
  430. if ALinger<0 then
  431. l.l_linger:=ALinger
  432. else
  433. l.l_linger:=0;
  434. if Not SetSockOpt(SOL_SOCKET, SO_LINGER, l, SizeOf(L)) then
  435. Raise ESocketError.CreateFmt('Failed to set linger: %d',[socketerror]);
  436. end;
  437. procedure TSocketServer.SetReuseAddress(AValue: Boolean);
  438. Var
  439. L : cint;
  440. begin
  441. L:=Ord(AValue);
  442. {$IFDEF UNIX}
  443. if not SetSockOpt(SOL_SOCKET, SO_REUSEADDR , L, SizeOf(L)) then
  444. Raise ESocketError.CreateFmt('Failed to set SO_REUSEADDR to %d: %d',[l,socketerror]);
  445. {$ENDIF}
  446. end;
  447. procedure TSocketServer.SetKeepAlive(AValue: Boolean);
  448. Var
  449. L : cint;
  450. begin
  451. L:=Ord(AValue);
  452. {$IFDEF UNIX}
  453. if Not SetSockOpt(SOL_SOCKET, SO_KEEPALIVE, L, SizeOf(L)) then
  454. Raise ESocketError.CreateFmt('Failed to set SO_REUSEADDR to %d: %d',[l,socketerror]);
  455. {$ENDIF}
  456. end;
  457. { ---------------------------------------------------------------------
  458. TInetServer
  459. ---------------------------------------------------------------------}
  460. Constructor TInetServer.Create(APort: Word);
  461. begin
  462. Create('0.0.0.0', aPort);
  463. end;
  464. Constructor TInetServer.Create(const aHost: string; const APort: Word);
  465. Var S : longint;
  466. begin
  467. FHost:=aHost;
  468. FPort:=APort;
  469. S:=Sockets.FpSocket(AF_INET,SOCK_STREAM,0);
  470. If S=-1 Then
  471. Raise ESocketError.Create(seCreationFailed,[Format('%d',[APort])]);
  472. Inherited Create(S);
  473. end;
  474. Procedure TInetServer.Bind;
  475. begin
  476. Faddr.sin_family := AF_INET;
  477. Faddr.sin_port := ShortHostToNet(FPort);
  478. Faddr.sin_addr.s_addr := LongWord(StrToNetAddr(FHost));
  479. if Sockets.fpBind(FSocket, @FAddr, Sizeof(FAddr))<>0 then
  480. raise ESocketError.Create(seBindFailed, [IntToStr(FPort)]);
  481. FBound:=True;
  482. end;
  483. Function TInetServer.SockToStream (ASocket : Longint) : TSocketStream;
  484. begin
  485. Result:=TInetSocket.Create(ASocket);
  486. (Result as TInetSocket).FHost:='';
  487. (Result as TInetSocket).FPort:=FPort;
  488. end;
  489. Function TInetServer.Accept : Longint;
  490. Var l : longint;
  491. begin
  492. L:=SizeOf(FAddr);
  493. Result:=Sockets.fpAccept(Socket,@Faddr,@L);
  494. If Result<0 then
  495. {$ifdef Unix}
  496. If SocketError=ESysEWOULDBLOCK then
  497. Raise ESocketError.Create(seAcceptWouldBlock,[socket])
  498. else
  499. {$endif}
  500. Raise ESocketError.Create(seAcceptFailed,[Socket,SocketError]);
  501. end;
  502. { ---------------------------------------------------------------------
  503. TUnixServer
  504. ---------------------------------------------------------------------}
  505. {$ifdef Unix}
  506. Constructor TUnixServer.Create(AFileName : String);
  507. Var S : Longint;
  508. begin
  509. FFileName:=AFileName;
  510. S:=Sockets.fpSocket(AF_UNIX,SOCK_STREAM,0);
  511. If S=-1 then
  512. Raise ESocketError.Create(seCreationFailed,[AFileName])
  513. else
  514. Inherited Create(S);
  515. end;
  516. Procedure TUnixServer.Close;
  517. begin
  518. Inherited Close;
  519. DeleteFile(FFileName);
  520. FFileName:='';
  521. end;
  522. Procedure TUnixServer.Bind;
  523. var
  524. AddrLen : longint;
  525. begin
  526. Str2UnixSockAddr(FFilename,FUnixAddr,AddrLen);
  527. If Sockets.FpBind(Socket,@FUnixAddr,AddrLen)<>0 then
  528. Raise ESocketError.Create(seBindFailed,[FFileName]);
  529. FBound:=True;
  530. end;
  531. Function TUnixServer.Accept : Longint;
  532. Var L : longint;
  533. begin
  534. L:=Length(FFileName);
  535. Result:=Sockets.fpAccept(Socket,@FUnixAddr,@L);
  536. If Result<0 then
  537. If SocketError=ESysEWOULDBLOCK then
  538. Raise ESocketError.Create(seAcceptWouldBlock,[socket])
  539. else
  540. Raise ESocketError.Create(seAcceptFailed,[socket,SocketError]);
  541. end;
  542. Function TUnixServer.SockToStream (ASocket : Longint) : TSocketStream;
  543. begin
  544. Result:=TUnixSocket.Create(ASocket);
  545. (Result as TUnixSocket).FFileName:=FFileName;
  546. end;
  547. {$endif}
  548. { ---------------------------------------------------------------------
  549. TInetSocket
  550. ---------------------------------------------------------------------}
  551. Constructor TInetSocket.Create(ASocket : Longint);
  552. begin
  553. Inherited Create(ASocket);
  554. end;
  555. Constructor TInetSocket.Create(const AHost: String; APort: Word);
  556. Var
  557. S : Longint;
  558. begin
  559. FHost:=AHost;
  560. FPort:=APort;
  561. S:=fpSocket(AF_INET,SOCK_STREAM,0);
  562. DoConnect(S);
  563. Inherited Create(S);
  564. end;
  565. Procedure TInetSocket.DoConnect(ASocket : Longint);
  566. Var
  567. A : THostAddr;
  568. addr: TInetSockAddr;
  569. begin
  570. A := StrToHostAddr(FHost);
  571. if A.s_bytes[1] = 0 then
  572. With THostResolver.Create(Nil) do
  573. try
  574. If Not NameLookup(FHost) then
  575. raise ESocketError.Create(seHostNotFound, [FHost]);
  576. A:=HostAddress;
  577. finally
  578. free;
  579. end;
  580. addr.sin_family := AF_INET;
  581. addr.sin_port := ShortHostToNet(FPort);
  582. addr.sin_addr.s_addr := HostToNet(a.s_addr);
  583. If Sockets.fpConnect(ASocket, @addr, sizeof(addr))<>0 then
  584. raise ESocketError.Create(seConnectFailed, [Format('%s:%d',[FHost, FPort])]);
  585. end;
  586. { ---------------------------------------------------------------------
  587. TUnixSocket
  588. ---------------------------------------------------------------------}
  589. {$ifdef Unix}
  590. Constructor TUnixSocket.Create(ASocket : Longint);
  591. begin
  592. Inherited Create(ASocket);
  593. end;
  594. Constructor TUnixSocket.Create(AFileName : String);
  595. Var S : Longint;
  596. begin
  597. FFileName:=AFileName;
  598. S:=FpSocket(AF_UNIX,SOCK_STREAM,0);
  599. DoConnect(S);
  600. Inherited Create(S);
  601. end;
  602. Procedure TUnixSocket.DoConnect(ASocket : longint);
  603. Var
  604. UnixAddr : TUnixSockAddr;
  605. AddrLen : longint;
  606. begin
  607. Str2UnixSockAddr(FFilename,UnixAddr,AddrLen);
  608. If FpConnect(ASocket,@UnixAddr,AddrLen)<>0 then
  609. Raise ESocketError.Create(seConnectFailed,[FFilename]);
  610. end;
  611. {$endif}
  612. end.