我需要按照确定的顺序从 Client 向 Server 发送数据,服务器也可以按照Client发送的相同顺序接收这些数据。在下面的代码中,存在一个问题,即像下一个数据的数据一样接收数据(即控制字节 1 )。
例如:
在客户上,我有以下几封邮件发送 1 ( $sudo apt-get install php-mbstring
$sudo apt-get install php-xml
)
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.
答案 0 :(得分:1)
客户端与服务器的数据大小不一致。
type
Connection = (Desktop, _Input);
Delphi中枚举的默认大小为byte
。这样做本身可以,但是您在客户端和服务器中对它们的处理方式不同。
您使用SendInt()
函数从客户端发送消息,该函数将转换为整数。
在服务器端,您将以SizeOf(_connection)
的形式接收它,它只是一个字节。由于字节顺序,1
保留在缓冲区中,随后被读入dwC
。
您可以通过在项目选项中将Minimum enum size
设置为doubleword
或作为字节发送来纠正错误。
评论后编辑
实际上,您还有另一个错误或误解。
从您发送的客户端
SendInt(Sock, Ord(Connection._Input))
由服务器作为
接收var
Check: BOOL;
....
recv(Sock, Check, SizeOf(Check), 0) ,
然后将其写为
Writeln(BoolToStr(Check));
,控制台显示“ -1”。但这不是错误,已记录在案:
Value of B Value of UseBoolStrs Value of returned string
true false '-1'
也许您想将其显示为枚举值。