|
Как правильно написать сокет-сервер?
#35066473
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
Ссылка на профиль пользователя:
|
Участник
Откуда: г.Костанай, Казахстан
Сообщения: 99
|
|
Привет знатокам!
Написал сокет-сервер как сом-объект (dll). Все хорошо, сокет открывается, слушается, данные из него читаются, но само приложение, использующее библиотеку, тормозит и дальше программа не может выполнить остальные свои функции, что не есть хорошо. Используются не блокирующие сокеты. Выкладываю весь исходник:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125.
unit Utestlib;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
ComObj, ActiveX, testlib_TLB, StdVcl, Dialogs, WinSock, SysUtils, Windows;
type
TApp = class(TAutoObject, IApp)
protected
procedure OpenSocket; safecall;
end;
type
ThreadData = record
Socket: TSocket;
end;
PThreadData = ^ThreadData;
var
WSAData: TWSAData;
ListenSocket, ClientSocket: TSocket;
Info: PThreadData;
SockAddr: TSockAddr;
ThreadId: THandle;
hClientThread: Thandle;
Arg : u_long;
s: TSocket;
const
Port = word( 5555 );
implementation
uses ComServ;
//////////////////////////////////////////
procedure SocketThread(Info: PThreadData);
var
SockName: TSockAddr;
NameLen, OptLen: Integer;
buf : array[ 0 .. 35 ] of byte;
RecvSize: integer;
BuffSize,k: integer;
str : string;
error : integer;
begin
s := Info^.Socket;
try
NameLen := SizeOf(TSockAddr);
if GetPeerName(s, SockName, NameLen) <> 0 then exit;
ShowMessage('Client accepted');
OptLen := SizeOf(BuffSize);
if GetSockOpt(s, SOL_SOCKET, SO_RCVBUF, pointer(@BuffSize), OptLen) <> 0 then exit;
try
repeat
RecvSize := recv(s, Buf[ 0 ], Length(Buf), 0 );
if RecvSize = SOCKET_ERROR then
Begin
error := WSAGetLastError();
if (error<>WSAEWOULDBLOCK) then
continue
else RecvSize := 1
end
else
sleep( 5 );
if RecvSize > 1 then
ShowMessage('Received from client ...');
until RecvSize <= 0 ;
finally
end;
ShowMessage('Client disconnected ...');
finally
CloseSocket(s);
Dispose(Info);
end;
end;
//////////////////////////////////////////
procedure TApp.OpenSocket;
begin
ShowMessage('WSA Initialize ...');
if WSAStartup($ 101 , WSAData) <> 0 then exit;
try
ListenSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
// non bloking
Arg:= 1 ;
IOCtlSocket(ListenSocket,FIONBIO,Arg);
//
if ListenSocket = INVALID_SOCKET then exit;
try
FillChar(SockAddr, SizeOf(TSockAddr), 0 );
SockAddr.sin_family := AF_INET;
SockAddr.sin_port := htons(Port);
SockAddr.sin_addr.S_addr := INADDR_ANY;
if Bind(ListenSocket, SockAddr, SizeOf(TSockAddr)) <> 0 then exit;
if listen(ListenSocket, SOMAXCONN) <> 0 then exit;
repeat
ClientSocket := accept(ListenSocket, nil, nil);
if ClientSocket <> INVALID_SOCKET then
begin
New(Info);
Info^.Socket := ClientSocket;
hClientThread := BeginThread(nil, 0 , @SocketThread, Info, 0 , ThreadId);
if hClientThread <> 0 then CloseHandle(hClientThread);
end;
until false;
finally
Arg:= 0 ;
IOCtlSocket(ListenSocket,FIONBIO,Arg);
CloseSocket(ListenSocket);
end;
finally
WSACleanup;
end;
end;
initialization
TAutoObjectFactory.Create(ComServer, TApp, Class_App,
ciMultiInstance, tmApartment);
end.
что я не так делал?
|
|
|