Мне нужно отправить данные с Клиента на Сервер в определенной последовательности, где Сервер может получать эти данные также по той же последовательности, отправленной Клиентом. В приведенном ниже коде существует проблема, связанная с тем, что данные (то есть байт управления, 1 ) принимаются как данные следующих данных.
Ex:
Вкл. Клиент У меня есть следующий фрагмент, который отправляет 1 (Connection._Input
)
if SendInt(Sock, Ord(Connection._Input)) <= 0 then
Exit;
Этот байт, отправленный выше, на Сервер , правильный получен для переменной Check
, но вместо этого получен на dwC
.
См:
Как можно решить?
Вот полный код:
Клиент:
program _Client;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows,
WinSock,
SysUtils;
type
Connection = (Desktop, _Input);
const
SendBuf: array [0 .. 9] of AnsiChar = ('A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', #0);
function SendInt(S: TSocket; I: Integer): Integer;
begin
Result := send(S, I, SizeOf(I), 0);
end;
function ConnectServer: TSocket;
var
Wsa: WSAData;
Client: sockaddr_in;
S: TSocket;
Rslt: Integer;
begin
S := INVALID_SOCKET;
try
Rslt := WSAStartup(MakeWord(2, 2), Wsa);
if Rslt = NO_ERROR then
begin
S := socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if S <> INVALID_SOCKET then
begin
Client.sin_family := AF_INET;
Client.sin_addr.s_addr := inet_addr('192.168.15.6');
Client.sin_port := htons(5099);
if connect(S, Client, SizeOf(Client)) <> SOCKET_ERROR then
Writeln('Connected successfully!');
end;
end;
except
Writeln(SysErrorMessage(WSAGetLastError));
end;
Result := S;
end;
function DesktopThread(P: Pointer): DWORD; stdcall;
var
Sock: TSocket;
dwC, dwD, dwE, dwF, dwG: DWORD;
A, B: Integer;
begin
Result := 0;
Sock := ConnectServer;
if send(Sock, SendBuf, SizeOf(SendBuf), 0) <= 0 then
Exit;
if SendInt(Sock, Ord(Connection.Desktop)) <= 0 then
Exit;
dwC := 111;
dwD := 222;
dwE := 333;
dwF := 444;
dwG := 555;
repeat
if recv(Sock, A, SizeOf(A), 0) <= 0 then
Exit;
if recv(Sock, B, SizeOf(B), 0) <= 0 then
Exit;
if SendInt(Sock, Ord(Connection._Input)) <= 0 then
Exit;
if SendInt(Sock, dwC) <= 0 then
Exit;
if SendInt(Sock, dwD) <= 0 then
Exit;
if SendInt(Sock, dwE) <= 0 then
Exit;
if SendInt(Sock, dwF) <= 0 then
Exit;
if SendInt(Sock, dwG) <= 0 then
Exit;
// Writeln(Format('%s', [SysErrorMessage(WSAGetLastError)]));
Writeln(Format('dwC: %d, dwD: %d, dwE: %d, dwF: %d, dwG: %d',
[dwC, dwD, dwE, dwF, dwG]));
until True;
end;
var
ThrId: Cardinal;
begin
try
CreateThread(nil, 0, @DesktopThread, nil, 0, ThrId);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
Сервер:
program _Server;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows,
WinSock,
SysUtils;
type
Connection = (Desktop, Input, _End);
const
Buffer: array [0 .. 9] of AnsiChar = ('A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', #0);
function SendInt(S: TSocket; I: Integer): Integer;
begin
Result := send(S, I, SizeOf(I), 0);
end;
function ClientThread(P: Pointer): DWORD; stdcall;
var
Buf: array [0 .. SizeOf(Buffer) - 1] of AnsiChar;
Sock: TSocket;
Check: BOOL;
A, B: Integer;
_connection: Connection;
dwC, dwD, dwE, dwF, dwG: DWORD;
begin
Result := 0;
Sock := TSocket(P);
if recv(Sock, Buf, SizeOf(Buffer), 0) <= 0 then
begin
closesocket(Sock);
Result := 0;
Exit;
end;
if not CompareMem(@Buf, @Buffer, SizeOf(Buffer)) then
begin
closesocket(Sock);
Result := 0;
Exit;
end;
if recv(Sock, _connection, SizeOf(_connection), 0) <= 0 then
begin
closesocket(Sock);
Result := 0;
Exit;
end;
if _connection = Connection.Desktop then
begin
A := 666;
B := 777;
repeat
if SendInt(Sock, A) <= 0 then
Exit;
if SendInt(Sock, B) <= 0 then
Exit;
if recv(Sock, Check, SizeOf(Check), 0) <= 0 then
Exit;
Writeln(BoolToStr(Check));
{ if not Check then
continue; }
if recv(Sock, dwC, SizeOf(dwC), 0) <= 0 then
Exit;
if recv(Sock, dwD, SizeOf(dwD), 0) <= 0 then
Exit;
if recv(Sock, dwE, SizeOf(dwE), 0) <= 0 then
Exit;
if recv(Sock, dwF, SizeOf(dwF), 0) <= 0 then
Exit;
if recv(Sock, dwG, SizeOf(dwG), 0) <= 0 then
Exit;
// Writeln(Format('%s', [SysErrorMessage(WSAGetLastError)]));
Writeln(Format('dwC: %d, dwD: %d, dwE: %d, dwF: %d, dwG: %d',
[dwC, dwD, dwE, dwF, dwG]));
until True;
end;
end;
function StartServer(Port: Integer): Boolean;
var
_wsdata: WSAData;
serverSocket, S: TSocket;
_addrIn, _addr: sockaddr_in;
addrSize: Integer;
tid: Cardinal;
begin
Result := False;
if WSAStartup(MakeWord(2, 2), _wsdata) <> 0 then
Exit;
serverSocket := socket(AF_INET, SOCK_STREAM, 0);
if serverSocket = INVALID_SOCKET then
Exit;
_addrIn.sin_family := AF_INET;
_addrIn.sin_addr.S_addr := INADDR_ANY;
_addrIn.sin_port := htons(Port);
if bind(serverSocket, _addrIn, SizeOf(_addrIn)) = SOCKET_ERROR then
Exit;
if listen(serverSocket, SOMAXCONN) = SOCKET_ERROR then
Exit;
addrSize := SizeOf(_addrIn);
getsockname(serverSocket, _addrIn, addrSize);
Writeln(Format('Listening on port %d.' + #13, [ntohs(_addrIn.sin_port)]));
while True do
begin
S := accept(serverSocket, @_addr, @addrSize);
CreateThread(nil, 0, @ClientThread, Pointer(S), 0, tid);
end;
Result := True;
end;
begin
try
if not StartServer(5099) then
Writeln(SysErrorMessage(WSAGetLastError));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.