Как сделать просто отправить / получить целочисленное значение, используя родной WinSock API в Delphi? - PullRequest
0 голосов
/ 16 апреля 2019

Как правильно отправить / получить целочисленное значение, используя собственный winsock только в одной строке, аналогично коду C ++, приведенному ниже?Я пытался перевести это, но не знаю, если это правильно.Может кто-то помочь мне, пожалуйста?

C ++:

enum MyEnum { element01, element02 };
int width;

int SendInt(SOCKET sock, int i)
{
   return Send(sock, (char *) &i, sizeof(i), 0);
}

if(SendInt(sock, MyEnum::element01) <= 0) return;
if(SendInt(sock, 0) <= 0) return;
if(recv(sock, (char *) &width, sizeof(width), 0) <= 0) return;

Delphi:

type
  MyEnum = (element01, element02);

var
 Width: Integer;

function SendInt(S: TSocket; I: Integer): Integer;
begin
  Result := send(S, PAnsiChar(I)^, Length(IntToStr(I)), 0);
end;

if SendInt(Sock, Integer(MyEnum.element01)) <= 0 then Exit;
if SendInt(Sock, 0) <= 0 then Exit;
if recv(Sock, PAnsiChar(Width)^, Length(IntToStr(Width)), 0) <= 0 then Exit;

Ответы [ 2 ]

3 голосов
/ 16 апреля 2019

Вы используете:

function SendInt(S: TSocket; I: Integer): Integer;
begin
  Result := send(S, PAnsiChar(I)^, Length(IntToStr(I)), 0);
end;

Второй параметр send() является нетипизированным параметром const , что означает, что вы можете передать все, что имеет адрес, , но приведениецелое число к указателю, а затем разыменование это, безусловно, не правильно .

Вы можете просто сделать это:

begin
  Result := send(S, I, SizeOf(I), 0);
end;

Хотя вам, возможно, придется изменить порядковый номер, используя htonl () :

begin
  // I := htonl(I); ??
  Result := send(S, I, SizeOf(I), 0);
end;

Вы должны попробовать обе альтернативы и посмотреть, что из этого получится.Один из них правильный.

Вы должны также передать целое число таким же образом, используя recv () .Возможно, вам придется использовать ntohl () (противоположно htonl () ) после вызова recv () :

function RecvInt(S: TSocket; var J: Integer): Integer;
begin
  Result := recv(S, J, SizeOf(J), 0);
  // J := ntohl(J); ??
end;
2 голосов
/ 16 апреля 2019

Звонок на send неправильный.Вы должны предоставить нетипизированный буфер для байтов, которые будут отправлены, и количество байтов.Абсолютно нет места для IntToStr здесь.

Result := send(S, I, SizeOf(I), 0);

И аналогично для вызова recv.

if recv(Sock, Width, SizeOf(Width), 0) <= 0 then Exit;

Идиоматично использовать Ord() для получения порядкового значенияперечислимого типа Delphi, поэтому Ord(MyEnum.element01), а не Integer(MyEnum.element01), но конечный результат будет точно таким же.

Ваш код не преобразуется между порядком байтов хоста и сети.Но тогда и код C ++ не работает.

...