ΠΠΈΡΡ, ΡΠΈΡΠ°ΡΡΠ°Ρ Π΄Π°Π½Π½ΡΠ΅, ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΎΠ±ΡΡΠ½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ β ΠΏΠΎΡΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ Π½Π°ΡΠ»Π΅Π΄Π½ΠΈΠΊΠ° ΠΎΡ ΠΊΠ»Π°ΡΡΠ° TThread. ΠΡ Π½Π΅ Π±ΡΠ΄Π΅ΠΌ Π²ΠΎΠ·Π»Π°Π³Π°ΡΡ Π½Π° ΡΡΡ Π½ΠΈΡΡ Π·Π°Π΄Π°ΡΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΎΠΊΠ΅ΡΠ°, β ΠΏΡΡΡΡ ΠΎΠ½ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π² Π³Π»Π°Π²Π½ΠΎΠΉ Π½ΠΈΡΠΈ, Π° Π·Π°ΡΠ΅ΠΌ Π΅Π³ΠΎ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ Π² Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠΎΡ ΡΠ°Π½ΡΠ΅Ρ Π΅Π³ΠΎ Π² ΡΠ²ΠΎΠ΅ΠΌ Π²Π½ΡΡΡΠ΅Π½Π½Π΅ΠΌ ΠΏΠΎΠ»Π΅ FSocket. ΠΠΎΠ΄ Π½ΠΈΡΠΈ, ΡΠΈΡΠ°ΡΡΠ΅ΠΉ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΠΏΠΎΠΊΠ°Π·Π°Π½ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 2.7.
ΠΠΈΡΡΠΈΠ½Π³ 2.7. ΠΠΎΠ΄ "ΡΠΈΡΠ°ΡΡΠ΅ΠΉ" Π½ΠΈΡΠΈunit ReceiveThread;
{
Π ΡΡΠΎΠΌ ΠΌΠΎΠ΄ΡΠ»Π΅ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½Π°Ρ Π½ΠΈΡΡ UDP-ΡΠ°ΡΠ°, ΠΎΡΠ²Π΅ΡΠ°ΡΡΠ°Ρ Π·Π° ΠΏΡΠΈΠ΅ΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ.
}
interface
uses
SysUtils, Classes, WinSock;
type
TReceiveThread = class(TThread)
private
// Π‘ΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π² Π»ΠΎΠ³,
// Ρ ΡΠ°Π½ΠΈΡΡΡ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠΌ ΠΏΠΎΠ»Π΅, Ρ.ΠΊ. ΠΌΠ΅ΡΠΎΠ΄, Π²ΡΠ·ΡΠ²Π°ΡΡΠΈΠΉΡΡ ΡΠ΅ΡΠ΅Π·
// Synchronize, Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ ΠΈΠΌΠ΅ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ².
FMessage: string;
// Π‘ΠΎΠΊΠ΅Ρ, ΠΏΠΎΠ»ΡΡΠ°ΡΡΠΈΠΉ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ
FSocket: TSocket;
// ΠΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ Π΄Π»Ρ Π²ΡΠ·ΠΎΠ²Π° ΡΠ΅ΡΠ΅Π· Synchronize
procedure DoLogMessage;
protected
procedure Execute; override;
// ΠΡΠ²ΠΎΠ΄ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π² Π»ΠΎΠ³ Π³Π»Π°Π²Π½ΠΎΠΉ ΡΠΎΡΠΌΡ
procedure LogMessage(const Msg: string);
public
constructor Create(ServerSocket: TSocket);
end;
implementation
uses ChatMainUnit;
{TReceiveThread}
// Π‘ΠΎΠΊΠ΅Ρ, ΠΏΠΎΠ»ΡΡΠ°ΡΡΠΈΠΉ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π² Π³Π»Π°Π²Π½ΠΎΠΉ Π½ΠΈΡΠΈ,
// Π° ΡΡΠ΄Π° ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ ΡΠ΅ΡΠ΅Π· ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠ°
constructor TReceiveThread.Create(ServerSocket: TSocket);
begin
FSocket := ServerSocket;
inherited Create(False);
end;
procedure TReceiveThread.Execute;
var
// ΠΡΡΠ΅Ρ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ.
// Π Π°Π·ΠΌΠ΅Ρ ΡΠ°Π²Π΅Π½ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΌΡ ΡΠ°Π·ΠΌΠ΅ΡΡ UDP-Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ
Buffer: array[0..65506] of Byte;
// ΠΠ΄ΡΠ΅Ρ, Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΏΡΠΈΡΠ»ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅
RecvAddr: TSockAddr;
RecvLen, AddrLen: Integer;
Msg: string;
begin
// ΠΠ°ΡΠΈΠ½Π°Π΅ΠΌ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΡΠΉ ΡΠΈΠΊΠ», Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΡΠ΅ΡΠ°ΡΠΈΠΈ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ
// ΡΠΈΡΠ°Π΅ΡΡΡ ΠΎΠ΄Π½Π° Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΠ°
repeat
AddrLen := SizeOf(RecvAddr);
// ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ
RecvLen :=
recvfrom(FSocket, Buffer, SizeOf(Buffer), 0, RecvAddr, AddrLen);
// Π’Π°ΠΊ ΠΊΠ°ΠΊ UDP Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅, ΠΎΡΠΈΠ±ΠΊΡ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ recvfrom
// ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ, ΡΠΎΠ»ΡΠΊΠΎ Π΅ΡΠ»ΠΈ ΡΠ»ΡΡΠΈΠ»ΠΎΡΡ ΡΡΠΎ-ΡΠΎ ΡΠΎΠ²ΡΠ΅ΠΌ
// ΡΠΊΡΡΡΠ°ΠΎΡΠ΄ΠΈΠ½Π°ΡΠ½ΠΎΠ΅. Π ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π·Π°Π²Π΅ΡΡΠ°Π΅ΠΌ ΡΠ°Π±ΠΎΡΡ Π½ΠΈΡΠΈ.
if RecvLen < 0 then
begin
LogMessage('ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ: ' + GetErrorString);
// ΠΠ΅ΡΠ΅Π²ΠΎΠ΄ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π³Π»Π°Π²Π½ΠΎΠΉ ΡΠΎΡΠΌΡ
// Π² ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ "Π‘Π΅ΡΠ²Π΅Ρ Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ"
SynchronizΠ΅(ChatForm.OnStopServer);
Break;
end;
// Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ Π½ΡΠΆΠ½ΡΠΉ ΡΠ°Π·ΠΌΠ΅Ρ ΡΡΡΠΎΠΊΠΈ
SetLength(Msg, RecvLen);
// ΠΈ ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ Π² Π½Π΅Π΅ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ ΠΈΠ· Π±ΡΡΠ΅ΡΠ°
if RecvLen > 0 then Move(Buffer, Msg[1], RecvLen);
LogMessage('Π‘ΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Ρ Π°Π΄ΡΠ΅ΡΠ° ' + inet_ntoa(RecvAddr.sin_addr) + ':' +
IntToStr(ntohs(RecvAddr.sin_port)) + ':' + Msg);
until False;
closesocket(FSocket);
end;
procedure TReceiveThread.LogMessage(const Msg: string);
begin
FMessage := Msg;
Synchronize(DoLogMessage);
end;
procedure TReceiveThread.DoLogMessage;
begin
ChatForm.AddMessageToLog(FMessage);
end;
end.
ΠΡΠΏΡΠ°Π²Π»ΡΡΡ Π΄Π°Π½Π½ΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈ ΠΈΠ· ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ Π½ΠΈΡΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΠ½ΠΊΡΠΈΡ sendto ΠΏΡΠΈ Π½Π°ΡΠΈΡ ΠΎΠ±ΡΠ΅ΠΌΠ°Ρ Π΄Π°Π½Π½ΡΡ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±ΡΠ΄Π΅Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°ΡΡ Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ Π΅Π΅ Π½ΠΈΡΡ (Π΄Π° ΠΈ ΠΏΡΠΈ Π±ΠΎΠ»ΡΡΠΈΡ ΠΎΠ±ΡΠ΅ΠΌΠ°Ρ Π΄Π°Π½Π½ΡΡ , ΠΊΠ°ΠΊ ΠΌΡ ΡΠ²ΠΈΠ΄ΠΈΠΌ Π² Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΌ, ΡΡΠΎΠ³ΠΎ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±ΡΠ²Π°Π΅Ρ). Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ Π΄Π²Π° ΡΠΎΠΊΠ΅ΡΠ°: ΠΎΠ΄ΠΈΠ½ Π΄Π»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, Π΄ΡΡΠ³ΠΎΠΉ Π΄Π»Ρ ΠΏΡΠΈΠ΅ΠΌΠ°. Π‘ΠΎΠΊΠ΅Ρ Π΄Π»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΡΡΠ°Π·Ρ ΠΆΠ΅ ΠΏΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΠΏΡΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ΅ ΡΠΎΠ±ΡΡΠΈΡ OnCreate Π³Π»Π°Π²Π½ΠΎΠΉ (ΠΈ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΠΎΠΉ) ΡΠΎΡΠΌΡ. ΠΠ΅ΡΠΊΡΠΈΠΏΡΠΎΡ ΡΠΎΠΊΠ΅ΡΠ° Ρ ΡΠ°Π½ΠΈΡΡΡ Π² ΠΏΠΎΠ»Π΅ FSendSocket. ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π½Π΅ ΠΏΡΠΈΠ½ΡΠΈΠΏΠΈΠ°Π»ΡΠ½ΠΎ, ΠΊΠ°ΠΊΠΎΠΉ ΠΏΠΎΡΡ Π·Π°ΠΉΠΌΠ΅Ρ ΡΡΠΎΡ ΡΠΎΠΊΠ΅Ρ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΡ Π΄ΠΎΠ²Π΅ΡΡΠ΅ΠΌ Π΅Π³ΠΎ Π²ΡΠ±ΠΎΡ ΡΠΈΡΡΠ΅ΠΌΠ΅ (Π»ΠΈΡΡΠΈΠ½Π³ 2.8).
ΠΠΈΡΡΠΈΠ½Π³ 2.8. ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ UDPChatprocedure TChatForm.FormCreate(Sender: TObject);
var
// ΠΠ΅Π· ΡΡΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π½Π΅ ΡΠ΄Π°ΡΡΡΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ ΡΠΎΠΊΠ΅ΡΠΎΠ²
WSAData: TWSAData;
// ΠΠ΄ΡΠ΅Ρ, ΠΊ ΠΊΠΎΡΠΎΡΠΎΠΌΡ ΠΏΡΠΈΠ²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΡΠΎΠΊΠ΅Ρ Π΄Π»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ
Addr: TSockAddr;
AddrLen: Integer;
begin
// ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ ΡΠΎΠΊΠ΅ΡΠΎΠ²
if WSAStartup($101, WSAData) <> 0 then
begin
MessageDlg('ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ WinSock',
mtError, [mbOK], 0);
Application.Terminate;
end;
// ΠΠ΅ΡΠ΅Π²ΠΎΠ΄ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π² ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ "Π‘Π΅ΡΠ²Π΅Ρ Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ"
OnStopServer;
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠΎΠΊΠ΅ΡΠ°
FSendSocket := socket(AF_INET, SOCK_DGPAM, IPROTO_UDP);
if FSendSocket = INVALID_SOCKET then
begin
MessageDlg('ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΠ΅Π³ΠΎ ΡΠΎΠΊΠ΅ΡΠ°:'#13#10 +
GetErrorString, mtError, [mbOK], 0);
Exit;
end;
// Π€ΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π°Π΄ΡΠ΅ΡΠ°, ΠΊ ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π±ΡΠ΄Π΅Ρ ΠΏΡΠΈΠ²ΡΠ·Π°Π½ ΡΠΎΠΊΠ΅Ρ
// Π΄Π»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ
FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0);
Addr.sin_family := AF_INET;
// ΠΡΡΡΡ ΡΠΈΡΡΠ΅ΠΌΠ° ΡΠ°ΠΌΠ° Π²ΡΠ±ΠΈΡΠ°Π΅Ρ Π΄Π»Ρ Π½Π΅Π³ΠΎ IP-Π°Π΄ΡΠ΅Ρ ΠΈ ΠΏΠΎΡΡ
Addr.sin_addr.S_addr := INADDR_ANY;
Addr.sin_port := 0;
// ΠΡΠΈΠ²ΡΠ·ΠΊΠ° ΡΠΎΠΊΠ΅ΡΠ° ΠΊ Π°Π΄ΡΠ΅ΡΡ
if bind(FSendSocket, Addr, SizeOf(Addr)) = SOCKET_ERROR then
begin
MessageDlg('ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ ΠΏΡΠΈΠ²ΡΠ·ΠΊΠ΅ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΠ΅Π³ΠΎ ΡΠΎΠΊΠ΅ΡΠ° ΠΊ Π°Π΄ΡΠ΅ΡΡ:'#13#10 +
GetErrorString, mtError, [mbOK], 0);
Exit;
end;
// Π£Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊΠΎΠΉ Π°Π΄ΡΠ΅Ρ ΡΠΈΡΡΠ΅ΠΌΠ° Π½Π°Π·Π½Π°ΡΠΈΠ»Π° ΡΠΎΠΊΠ΅ΡΡ
// ΠΡΠΎ Π½ΡΠΆΠ½ΠΎ Π΄Π»Ρ Π²ΡΠ²ΠΎΠ΄Π° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ Π΄Π»Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ
AddrLen := SizeOf(Addr);
if getsockname(FSendSocket, Addr, AddrLen) = SOCKET_ERROR then
begin
MessageDlg('ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ Π°Π΄ΡΠ΅ΡΠ° ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΠ΅Π³ΠΎ ΡΠΎΠΊΠ΅ΡΠ°:'#13#10 +
GetErrorString, mtError, [mbOK], 0);
Exit;
end;
// ΠΠ΅ Π·Π°Π±ΡΠ²Π°Π΅ΠΌ, ΡΡΠΎ Π½ΠΎΠΌΠ΅Ρ ΠΏΠΎΡΡΠ° Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ Π² ΡΠ΅ΡΠ΅Π²ΠΎΠΌ ΡΠΎΡΠΌΠ°ΡΠ΅,
// ΠΈ Π΅Π³ΠΎ Π½ΡΠΆΠ½ΠΎ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΡ ΠΊ ΠΎΠ±ΡΡΠ½ΠΎΠΌΡ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ htons.
LabelSendPort.Caption := 'ΠΠΎΡΡ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ: ' + IntToStr(ntohs(Addr.sin_port));
end;
Π‘ΠΎΠΊΠ΅Ρ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΏΡΠΈ Π½Π°ΠΆΠ°ΡΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΠ°ΠΏΡΡΡΠΈΡΡ ΠΈ ΠΏΡΠΈΠ²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΠΊ ΡΠΎΠΌΡ ΠΏΠΎΡΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΊΠ°Π·Π°Π» ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ. Π ΡΠ»ΡΡΠ°Π΅ Π΅Π³ΠΎ ΡΡΠΏΠ΅ΡΠ½ΠΎΠ³ΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ Π½ΠΈΡΡ, ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ ΡΡΠΎΡ ΡΠΎΠΊΠ΅Ρ, ΠΈ Π²ΡΠ΅ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Ρ Π½ΠΈΠΌ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΡΡΠ° Π½ΠΈΡΡ. ΠΠΈΡΡ Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΡΡΠΈΠΌ ΡΠΎΠΊΠ΅ΡΠΎΠΌ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΡΡΠ»ΠΎΠ²Π½ΠΎ Π½Π°Π·ΡΠ²Π°ΡΡ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ. ΠΠΎΠ΄ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° Π½Π°ΠΆΠ°ΡΠΈΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΠ°ΠΏΡΡΡΠΈΡΡ ΠΏΠΎΠΊΠ°Π·Π°Π½ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 2.9.
ΠΠΈΡΡΠΈΠ½Π³ 2.9. ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π½Π°ΠΆΠ°ΡΠΈΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΠ°ΠΏΡΡΡΠΈΡΡ// Π Π΅Π°ΠΊΡΠΈΡ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡ "ΠΠ°ΠΏΡΡΡΠΈΡΡ"
procedure TChatForm.BtnStartServerClick(Sender: TObject);
var
// Π‘ΠΎΠΊΠ΅Ρ Π΄Π»Ρ ΠΏΡΠΈΠ΅ΠΌΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ
ServerSocket: TSocket;
// ΠΠ΄ΡΠ΅Ρ, ΠΊ ΠΊΠΎΡΠΎΡΠΎΠΌΡ ΠΏΡΠΈΠ²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΡΠΎΠΊΠ΅Ρ Π΄Π»Ρ ΠΏΡΠΈΠ΅ΠΌΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ
ServerAddr: TSockAddr;
begin
// Π€ΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π°Π΄ΡΠ΅ΡΠ° ΡΠΎΠΊΠ΅ΡΠ° Π΄Π»Ρ ΠΏΡΠΈΠ΅ΠΌΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ
FillChar(ServerAddr.sin_zero, SizeOf(ServerAddr.sin_zero), 0);
ServerAddr.sin_family := AF_INET;
// IP-Π°Π΄ΡΠ΅Ρ ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ±ΡΠ°ΡΡ ΡΠΈΡΡΠ΅ΠΌΠ°, Π° ΠΏΠΎΡΡ Π½Π°Π·Π½Π°ΡΠ°Π΅ΠΌ ΡΠΎΡ,
// ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°Π΄Π°Π½ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΌ
ServerAddr.sin_addr.S_addr := INADDR_ANY;
try
// He Π·Π°Π±ΡΠ²Π°Π΅ΠΌ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΡ Π½ΠΎΠΌΠ΅Ρ ΠΏΠΎΡΡΠ° ΠΊ ΡΠ΅ΡΠ΅Π²ΠΎΠΌΡ ΡΠΎΡΠΌΠ°ΡΡ
// Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ htons
ServerAddr.sin_port := htons(StrToInt(EditServerPort.Text));
if ServerAddr.sin_port = 0 then
begin
MessageDlg('ΠΠΎΠΌΠ΅Ρ ΠΏΠΎΡΡΠ° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡΡ Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ 1-65535',
mtError, [mbOK], 0);
Exit;
end;
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠΎΠΊΠ΅ΡΠ° Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ
ServerSocket := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if ServerSocket = INVALID_SOCKET then
begin
MessageDlg('ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΡΠΎΠΊΠ΅ΡΠ°: '#13#10 + GetErrorString,
mtError, [mbOK], 0);
Exit;
end;
// ΠΏΡΠΈΠ²ΡΠ·ΠΊΠ° ΡΠΎΠΊΠ΅ΡΠ° ΠΊ Π°Π΄ΡΠ΅ΡΡ
if bind(ServerSocket, ServerAddr, SizeOf(ServerAddr)) = SOCKET_ERROR then
begin
MessageDlg('ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ ΠΏΡΠΈΠ²ΡΠ·ΠΊΠ΅ ΡΠΎΠΊΠ΅ΡΠ° ΠΊ Π°Π΄ΡΠ΅ΡΡ: '#13#10 + GetErrorString,
mtError, [mbOK], 0);
closesocket(ServerSocket);
Exit;
end;
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΈΡΠΈ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ»ΡΡΠ°ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ.
// Π‘ΠΎΠΊΠ΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ Π΅ΠΉ, ΠΈ Π΄Π°Π»ΡΡΠ΅ ΠΎΠ½Π° ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° Π½Π΅Π³ΠΎ.
TReceiveThread.Create(ServerSocket);
// ΠΠ΅ΡΠ΅Π²ΠΎΠ΄ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π² ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ "Π‘Π΅ΡΠ²Π΅Ρ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ"
LabelServerPort.Enabled := False;
EditServerPort.Enabled := False;
BtnStartServer.Enabled := False;