tfpsock3.pp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. program tcptest;
  2. {$mode objfpc}{$H+}
  3. uses
  4. {$IFDEF UNIX}
  5. cthreads,
  6. {$ENDIF}
  7. Classes, SysUtils, fpsockets, ctypes;
  8. const
  9. {$if defined(win32)}
  10. LibName = 'msvcrt';
  11. {$elseif defined(win64)}
  12. LibName = 'msvcrt';
  13. {$elseif defined(wince)}
  14. LibName = 'coredll';
  15. {$elseif defined(netware)}
  16. LibName = 'clib';
  17. {$elseif defined(netwlibc)}
  18. LibName = 'libc';
  19. {$elseif defined(macos)}
  20. LibName = 'StdCLib';
  21. {$elseif defined(beos)}
  22. LibName = 'root';
  23. {$else}
  24. LibName = 'c';
  25. {$endif}
  26. procedure CExit(status: cint); cdecl; external LibName name 'exit';
  27. const
  28. HelloStr = 'Hello Server';
  29. ReplyStr = 'Hello Client!';
  30. var ClientError, ServerError: String;
  31. procedure IPv4TestServer;
  32. var
  33. sock: TFPSocket;
  34. Conn: TFPSocketConnection;
  35. Received: String;
  36. begin
  37. ServerError := '';
  38. try
  39. sock := TCPSocket(stIPv4);
  40. try
  41. Bind(sock, '0.0.0.0', 1337);
  42. Listen(sock, 0);
  43. Conn := AcceptConnection(sock);
  44. try
  45. Received := ReceiveStr(Conn.Socket);
  46. sleep(500);
  47. SendStr(Conn.Socket, ReplyStr);
  48. finally
  49. CloseSocket(Conn.Socket);
  50. end;
  51. finally
  52. CloseSocket(sock);
  53. end;
  54. if Received <> HelloStr then
  55. ServerError := 'Unexpected response: ' + Received;
  56. except on E: Exception do
  57. ServerError := 'Exception: ' + E.Message;
  58. end;
  59. end;
  60. procedure IPv4TestClient;
  61. var
  62. sock: TFPSocket;
  63. Received: String;
  64. begin
  65. ClientError := '';
  66. try
  67. sock := TCPSocket(stIPv4);
  68. try
  69. Connect(sock, '127.0.0.1', 1337);
  70. SendStr(sock, HelloStr);
  71. Received := ReceiveStr(sock, 16);
  72. if Received <> ReplyStr then
  73. ClientError := 'Unexpected response: ' + Received;
  74. finally
  75. CloseSocket(sock);
  76. end;
  77. except on E: Exception do
  78. ClientError := 'Exception: ' + E.Message;
  79. end;
  80. end;
  81. procedure IPv6TestServer;
  82. var
  83. sock: TFPSocket;
  84. Conn: TFPSocketConnection;
  85. Received: String;
  86. begin
  87. ServerError := '';
  88. try
  89. sock := TCPSocket(stIPv6);
  90. try
  91. Bind(sock, '::0', 1337);
  92. Listen(sock, 0);
  93. Conn := AcceptConnection(sock);
  94. try
  95. Received := ReceiveStr(Conn.Socket);
  96. SendStr(Conn.Socket, ReplyStr);
  97. finally
  98. CloseSocket(Conn.Socket);
  99. end;
  100. finally
  101. CloseSocket(sock);
  102. end;
  103. if Received <> HelloStr then
  104. ServerError := 'Unexpected response: ' + Received;
  105. except on E: Exception do
  106. ServerError := 'Exception: ' + E.Message;
  107. end;
  108. end;
  109. procedure IPv6TestClient;
  110. var
  111. sock: TFPSocket;
  112. Received: String;
  113. begin
  114. ClientError := '';
  115. try
  116. sock := TCPSocket(stIPv6);
  117. try
  118. Connect(sock, '::1', 1337);
  119. SendStr(sock, HelloStr);
  120. Received := ReceiveStr(sock);
  121. if Received <> ReplyStr then
  122. ClientError := 'Unexpected response: ' + Received;
  123. finally
  124. CloseSocket(sock);
  125. end;
  126. except on E: Exception do
  127. ClientError := 'Exception: ' + E.Message;
  128. end;
  129. end;
  130. procedure DualStackTestServer;
  131. var
  132. sock: TFPSocket;
  133. Conn: TFPSocketConnection;
  134. Received: String;
  135. begin
  136. ServerError := '';
  137. try
  138. sock := TCPSocket(stIPDualStack);
  139. try
  140. Bind(sock, '::0', 1337);
  141. Listen(sock, 0);
  142. Conn := AcceptConnection(sock);
  143. try
  144. Received := ReceiveStr(Conn.Socket);
  145. SendStr(Conn.Socket, ReplyStr);
  146. finally
  147. CloseSocket(Conn.Socket);
  148. end;
  149. finally
  150. CloseSocket(sock);
  151. end;
  152. if not IsIPv4Mapped(Conn.ClientAddress) then
  153. ServerError := 'Expected IPv4 mapped Address, got ' + Conn.ClientAddress.Address;
  154. if Received <> HelloStr then
  155. ServerError := 'Unexpected response: ' + Received;
  156. except on E: Exception do
  157. ServerError := 'Exception: ' + E.Message;
  158. end;
  159. end;
  160. procedure CloseTestServer;
  161. var
  162. sock: TFPSocket;
  163. Conn: TFPSocketConnection;
  164. begin
  165. ServerError := '';
  166. try
  167. sock := TCPSocket(stIPv4);
  168. try
  169. Bind(sock, '0.0.0.0', 1337);
  170. Listen(sock, 0);
  171. Conn := AcceptConnection(sock);
  172. CloseSocket(Conn.Socket);
  173. finally
  174. CloseSocket(sock);
  175. end;
  176. except on E: Exception do
  177. ServerError := 'Exception: ' + E.Message;
  178. end;
  179. end;
  180. procedure CloseTestClient;
  181. var
  182. sock: TFPSocket;
  183. begin
  184. ClientError := '';
  185. try
  186. sock := TCPSocket(stIPv4);
  187. try
  188. Connect(sock, '127.0.0.1', 1337);
  189. Sleep(100);
  190. if not StreamClosed(sock) then
  191. begin
  192. ClientError := 'Should detect closed stream by server';
  193. Exit;
  194. end;
  195. try
  196. ReceiveStr(sock);
  197. ClientError := 'Should detect closed stream by server';
  198. except on E: EConnectionClosedException do
  199. end;
  200. finally
  201. CloseSocket(sock);
  202. end;
  203. except on E: Exception do
  204. ClientError := 'Exception: ' + E.Message;
  205. end;
  206. end;
  207. procedure DataAvailableTestClient;
  208. var
  209. sock: TFPSocket;
  210. begin
  211. ClientError := '';
  212. try
  213. sock := TCPSocket(stIPv4);
  214. try
  215. Connect(sock, '127.0.0.1', 1337);
  216. SendStr(sock, HelloStr);
  217. Sleep(600);
  218. if not DataAvailable(sock) then
  219. begin
  220. ClientError := 'Should have data from the server pending';
  221. Exit;
  222. end;
  223. if BytesAvailable(sock) <> Length(ReplyStr) then
  224. ClientError := 'Unexpected data length';
  225. finally
  226. CloseSocket(sock);
  227. end;
  228. except on E: Exception do
  229. ClientError := 'Exception: ' + E.Message;
  230. end;
  231. end;
  232. procedure ReceiveArrayTestServer;
  233. var
  234. sock: TFPSocket;
  235. Conn: TFPSocketConnection;
  236. Received: Array of Integer; // Hello Server = 12 chars = divisible by 4
  237. i:Integer;
  238. begin
  239. ServerError := '';
  240. try
  241. sock := TCPSocket(stIPv4);
  242. try
  243. Bind(sock, '0.0.0.0', 1337);
  244. Listen(sock, 0);
  245. Conn := AcceptConnection(sock);
  246. try
  247. Received := specialize ReceiveArray<Integer>(Conn.Socket);
  248. SendStr(Conn.Socket, ReplyStr);
  249. finally
  250. CloseSocket(Conn.Socket);
  251. end;
  252. finally
  253. CloseSocket(sock);
  254. end;
  255. if Length(Received) * SizeOf(Integer) <> Length(HelloStr) then
  256. begin
  257. ServerError := 'Unexpected response length ' + Length(Received).ToString;
  258. Exit;
  259. end;
  260. for i:=0 to Length(HelloStr) -1 do
  261. if PChar(@Received[0])[i]<>HelloStr[i+1] then
  262. begin
  263. ServerError := 'Unexpected response Char ' + PChar(@Received[0])[i] + '@' + i.ToString;;
  264. Exit;
  265. end;
  266. except on E: Exception do
  267. ServerError := 'Exception: ' + E.Message;
  268. end;
  269. end;
  270. procedure ReceiveArrayTestClient;
  271. var
  272. sock: TFPSocket;
  273. Received: Array of Char;
  274. i:Integer;
  275. begin
  276. ClientError := '';
  277. try
  278. sock := TCPSocket(stIPv4);
  279. try
  280. Connect(sock, '127.0.0.1', 1337);
  281. SendStr(sock, HelloStr);
  282. Received := specialize ReceiveArray<Char>(sock);
  283. finally
  284. CloseSocket(sock);
  285. end;
  286. if Length(Received) <> Length(ReplyStr) then
  287. begin
  288. ClientError := 'Unexpected response length ' + Length(Received).ToString;
  289. Exit;
  290. end;
  291. for i:=0 to Length(Received) -1 do
  292. if Received[i]<>ReplyStr[i+1] then
  293. begin
  294. ClientError := 'Unexpected response Char ' + Received[i] + '@' + i.ToString;
  295. Exit;
  296. end;
  297. except on E: Exception do
  298. ClientError := 'Exception: ' + E.Message;
  299. end;
  300. end;
  301. procedure ChunkTestServer;
  302. type
  303. TChunkString = String[16];
  304. var
  305. sock: TFPSocket;
  306. Conn: TFPSocketConnection;
  307. Received, toSend: TChunkString;
  308. begin
  309. ServerError := '';
  310. try
  311. sock := TCPSocket(stIPv4);
  312. try
  313. Bind(sock, '0.0.0.0', 1337);
  314. Listen(sock, 0);
  315. Conn := AcceptConnection(sock);
  316. try
  317. Received := specialize Receive<TChunkString>(Conn.Socket);
  318. ToSend := ReplyStr;
  319. // Send in two halves with time delay (client must block until full chunk)
  320. Send(Conn.Socket, @toSend, SizeOf(toSend) div 2);
  321. Sleep(400);
  322. Send(Conn.Socket, PByte(@toSend) + SizeOf(toSend) div 2, SizeOf(toSend) - SizeOf(toSend) div 2);
  323. finally
  324. CloseSocket(Conn.Socket);
  325. end;
  326. finally
  327. CloseSocket(sock);
  328. end;
  329. if Received <> HelloStr then
  330. ServerError := 'Unexpected response: ' + Received;
  331. except on E: Exception do
  332. ServerError := 'Exception: ' + E.Message;
  333. end;
  334. end;
  335. procedure ChunkTestClient;
  336. type
  337. TChunkString = String[16];
  338. var
  339. sock: TFPSocket;
  340. Received: TChunkString;
  341. begin
  342. ClientError := '';
  343. try
  344. sock := TCPSocket(stIPv4);
  345. try
  346. Connect(sock, '127.0.0.1', 1337);
  347. specialize Send<TChunkString>(sock, HelloStr);
  348. Received := specialize Receive<TChunkString>(sock);
  349. if Received <> ReplyStr then
  350. ClientError := 'Unexpected response: ' + Received;
  351. finally
  352. CloseSocket(sock);
  353. end;
  354. except on E: Exception do
  355. ClientError := 'Exception: ' + E.Message;
  356. end;
  357. end;
  358. procedure TestNonBlockingServer;
  359. var
  360. sock: TFPSocket;
  361. Conn: TFPSocketConnection;
  362. Received: String;
  363. begin
  364. ServerError := '';
  365. try
  366. sock := TCPSocket(stIPv4);
  367. try
  368. SetNonBlocking(sock, True);
  369. Bind(sock, '0.0.0.0', 1337);
  370. Listen(sock, 0);
  371. while not AcceptNonBlocking(sock).Unpack(Conn) do
  372. Sleep(100);
  373. try
  374. SetNonBlocking(Conn.Socket, True);
  375. repeat
  376. Received := ReceiveStr(Conn.Socket);
  377. Sleep(100);
  378. until Received<>'';
  379. Sleep(500);
  380. SendStr(Conn.Socket, ReplyStr);
  381. finally
  382. CloseSocket(Conn.Socket);
  383. end;
  384. finally
  385. CloseSocket(sock);
  386. end;
  387. if Received <> HelloStr then
  388. ServerError := 'Unexpected response: ' + Received;
  389. except on E: Exception do
  390. ServerError := 'Exception: ' + E.Message;
  391. end;
  392. end;
  393. procedure TestNonBlockingClient;
  394. var
  395. sock: TFPSocket;
  396. Received: Array of Char;
  397. State:TConnectionState;
  398. i:Integer;
  399. begin
  400. ClientError := '';
  401. try
  402. sock := TCPSocket(stIPv4);
  403. try
  404. SetNonBlocking(sock, True);
  405. Sleep(200);
  406. State := Connect(sock, '127.0.0.1', 1337);
  407. while State = csPending do
  408. begin
  409. Sleep(100);
  410. State:=ConnectionState(sock);
  411. end;
  412. if State <> csConnected then
  413. begin
  414. ClientError := 'Connection not successful';
  415. Exit;
  416. end;
  417. Sleep(200);
  418. SendStr(sock, HelloStr);
  419. repeat
  420. Received := specialize ReceiveArray<Char>(sock, 16);
  421. Sleep(100);
  422. until Received<>nil;
  423. finally
  424. CloseSocket(sock);
  425. end;
  426. for i:=0 to Length(Received) -1 do
  427. if Received[i]<>ReplyStr[i+1] then
  428. begin
  429. ClientError := 'Unexpected response Char ' + Received[i] + '@' + i.ToString;;
  430. Exit;
  431. end;
  432. except on E: Exception do
  433. ClientError := 'Exception: ' + E.Message;
  434. end;
  435. end;
  436. {$IfDef Unix}
  437. // Different behavior between winsock and berkley sockets
  438. // Seems like winsock does not provide refused when the server closes while pending
  439. procedure TestRefusedServer;
  440. var
  441. sock: TFPSocket;
  442. begin
  443. ServerError := '';
  444. try
  445. sock := TCPSocket(stIPv4);
  446. try
  447. Bind(sock, '0.0.0.0', 1337);
  448. Listen(sock, 1);
  449. finally
  450. CloseSocket(sock);
  451. end;
  452. except on E: Exception do
  453. ServerError := 'Exception: ' + E.Message;
  454. end;
  455. end;
  456. procedure TestRefusedClient;
  457. var
  458. sock: TFPSocket;
  459. State: TConnectionState;
  460. begin
  461. ClientError := '';
  462. try
  463. sock := TCPSocket(stIPv4);
  464. try
  465. SetNonBlocking(sock, True);
  466. Connect(sock, '127.0.0.1', 1337);
  467. Sleep(200);
  468. State:=ConnectionState(sock);
  469. if State <> csRefused then
  470. begin
  471. ClientError := 'Connection should be refused';
  472. Exit;
  473. end;
  474. finally
  475. CloseSocket(sock);
  476. end;
  477. except on E: Exception do
  478. ClientError := 'Exception: ' + E.Message;
  479. end;
  480. end;
  481. {$EndIf}
  482. procedure TestFragmentationServer;
  483. var
  484. sock: TFPSocket;
  485. Conn: TFPSocketConnection;
  486. begin
  487. ServerError := '';
  488. try
  489. sock := TCPSocket(stIPv4);
  490. try
  491. Bind(sock, '0.0.0.0', 1337);
  492. Listen(sock, 0);
  493. Conn := AcceptConnection(sock);
  494. try
  495. SetNonBlocking(Conn.Socket, True);
  496. try
  497. while not specialize ReceiveNonBlocking<LongInt>(Conn.Socket) do
  498. Sleep(50);
  499. ServerError := 'Should have thrown fragmentation exception';
  500. except on E: EFragmentedData do
  501. if Length(e.Fragment) <> SizeOf(Word) then
  502. ServerError := 'Unexpected Fragment Size';
  503. on E: Exception do
  504. raise E;
  505. end;
  506. finally
  507. CloseSocket(Conn.Socket);
  508. end;
  509. finally
  510. CloseSocket(sock);
  511. end;
  512. except on E: Exception do
  513. ServerError := 'Exception: ' + E.Message;
  514. end;
  515. end;
  516. procedure TestFragmentationClient;
  517. var
  518. sock: TFPSocket;
  519. begin
  520. ClientError := '';
  521. try
  522. sock := TCPSocket(stIPv4);
  523. try
  524. Connect(sock, '127.0.0.1', 1337);
  525. specialize Send<Word>(sock, 42);
  526. Sleep(100);
  527. finally
  528. CloseSocket(sock);
  529. end;
  530. except on E: Exception do
  531. ClientError := 'Exception: ' + E.Message;
  532. end;
  533. end;
  534. procedure TestFragmentedArrayServer;
  535. var
  536. sock: TFPSocket;
  537. Conn: TFPSocketConnection;
  538. begin
  539. ServerError := '';
  540. try
  541. sock := TCPSocket(stIPv4);
  542. try
  543. Bind(sock, '0.0.0.0', 1337);
  544. Listen(sock, 0);
  545. Conn := AcceptConnection(sock);
  546. try
  547. SetNonBlocking(Conn.Socket, True);
  548. try
  549. while specialize ReceiveArray<LongInt>(Conn.Socket) = nil do
  550. Sleep(50);
  551. ServerError := 'Should have thrown fragmentation exception';
  552. except on E: EFragmentedData do
  553. if Length(e.Fragment) <> SizeOf(Word) then
  554. ServerError := 'Unexpected Fragment Size';
  555. on E: Exception do
  556. raise E;
  557. end;
  558. finally
  559. CloseSocket(Conn.Socket);
  560. end;
  561. finally
  562. CloseSocket(sock);
  563. end;
  564. except on E: Exception do
  565. ServerError := 'Exception: ' + E.Message;
  566. end;
  567. end;
  568. procedure TestFragmentedArrayClient;
  569. var
  570. sock: TFPSocket;
  571. begin
  572. ClientError := '';
  573. try
  574. sock := TCPSocket(stIPv4);
  575. try
  576. Connect(sock, '127.0.0.1', 1337);
  577. specialize SendArray<Word>(sock, [42]);
  578. Sleep(100);
  579. finally
  580. CloseSocket(sock);
  581. end;
  582. except on E: Exception do
  583. ClientError := 'Exception: ' + E.Message;
  584. end;
  585. end;
  586. { When trying to read an array, and the array is fragmented, and you give it a
  587. read size thats larger than whats in the buffer, instead of a fragmented
  588. exception, a connection closed exception will be raised.
  589. This is suboptimal/undesired behavior, but arises from the internal calls to
  590. Receive, which raises an exception on end of stream. This test verifies that,
  591. arguably faulty behavior, so it may very well be fixed in the future }
  592. procedure TestFragmentedCloseServer;
  593. var
  594. sock: TFPSocket;
  595. Conn: TFPSocketConnection;
  596. begin
  597. ServerError := '';
  598. try
  599. sock := TCPSocket(stIPv4);
  600. try
  601. Bind(sock, '0.0.0.0', 1337);
  602. Listen(sock, 0);
  603. Conn := AcceptConnection(sock);
  604. try
  605. try
  606. Sleep(100);
  607. specialize ReceiveArray<LongInt>(Conn.Socket, 2);
  608. ServerError := 'Should have thrown ConnectionClosed Exception';
  609. except on E: EConnectionClosedException do ;
  610. on E: Exception do
  611. raise E;
  612. end;
  613. finally
  614. CloseSocket(Conn.Socket);
  615. end;
  616. finally
  617. CloseSocket(sock);
  618. end;
  619. except on E: Exception do
  620. ServerError := 'Exception: ' + E.Message;
  621. end;
  622. end;
  623. procedure TestFragmentedCloseClient;
  624. var
  625. sock: TFPSocket;
  626. begin
  627. ClientError := '';
  628. try
  629. sock := TCPSocket(stIPv4);
  630. try
  631. Connect(sock, '127.0.0.1', 1337);
  632. specialize SendArray<Word>(sock, [42, 43, 44]);
  633. Sleep(100);
  634. finally
  635. CloseSocket(sock);
  636. end;
  637. except on E: Exception do
  638. ClientError := 'Exception: ' + E.Message;
  639. end;
  640. end;
  641. type
  642. TTimeoutThread = class(TThread)
  643. protected
  644. procedure Execute;override;
  645. end;
  646. procedure TTimeoutThread.Execute;
  647. var
  648. i: Integer;
  649. begin
  650. for i:=1 to 100 do
  651. begin
  652. if Terminated then
  653. Exit;
  654. Sleep(100);
  655. end;
  656. if Terminated then
  657. Exit;
  658. WriteLn(' Timeout');
  659. // FPC Halt does not work with threads... so we just rawkill using libc
  660. cexit(1);
  661. end;
  662. procedure RunTest(const TestName: String; ASrv, ACli: TProcedure);
  663. var
  664. Timeout, SrvThread, CliThread: TThread;
  665. begin
  666. Write('Testing ', TestName, '...');
  667. SrvThread:=TThread.CreateAnonymousThread(ASrv);
  668. SrvThread.FreeOnTerminate := False;
  669. SrvThread.Start;
  670. CliThread:=TThread.CreateAnonymousThread(ACli);
  671. CliThread.FreeOnTerminate := False;
  672. CliThread.Start;
  673. Timeout:=TTimeoutThread.Create(false);
  674. SrvThread.WaitFor;
  675. if not ServerError.IsEmpty then
  676. begin
  677. WriteLn(LineEnding, ' Server Error: ', ServerError);
  678. Halt(1);
  679. end;
  680. CliThread.WaitFor;
  681. if not ClientError.IsEmpty then
  682. begin
  683. WriteLn(LineEnding, ' Client Error: ', ClientError);
  684. Halt(1);
  685. end;
  686. Timeout.Terminate;
  687. Timeout.Free;
  688. WriteLn(' Success!');
  689. CliThread.Free;
  690. SrvThread.Free;
  691. Sleep(800);
  692. end;
  693. begin
  694. RunTest('IPv4Test', @IPv4TestServer, @IPv4TestClient);
  695. RunTest('IPv6Test', @IPv6TestServer, @IPv6TestClient);
  696. RunTest('DualStackTest', @DualStackTestServer, @IPv4TestClient);
  697. RunTest('CloseTest', @CloseTestServer, @CloseTestClient);
  698. RunTest('DataAvailableTest', @IPv4TestServer, @DataAvailableTestClient);
  699. RunTest('ReceiveArrayTest', @ReceiveArrayTestServer, @ReceiveArrayTestClient);
  700. RunTest('ChunkTest', @ChunkTestServer, @ChunkTestClient);
  701. RunTest('NonBlockingTest', @TestNonBlockingServer, @TestNonBlockingClient);
  702. {$IfDef Unix}
  703. RunTest('RefusedTest', @TestRefusedServer, @TestRefusedClient);
  704. {$EndIf}
  705. RunTest('FragmentationTest', @TestFragmentationServer, @TestFragmentationClient);
  706. RunTest('FragmentedArrayTest', @TestFragmentedArrayServer, @TestFragmentedArrayClient);
  707. RunTest('FragmentedCloseTest', @TestFragmentedCloseServer, @TestFragmentedCloseClient);
  708. end.