我使用Delphi XE2和Indy10 UDP协议。 如果我使用ReceiveBuffer方法,我无法在客户端接收服务器回应。 我得到了“套接字错误#10040”,虽然我发回了非常小的回声 从服务器到客户端的消息。 控制台应用程序来说明我的问题如下。 提前谢谢。
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, IdGlobal, IdBaseComponent, IdComponent, IdSocketHandle,
IdUDPClient, IdUDPServer, IdUDPBase, IdStack;
type
TUDP_Serv = class(TIdUDPServer)
procedure udpSvUDPRead(AThread: TIdUDPListenerThread;
AData: TIdBytes; ABinding: TIdSocketHandle);
end;
var
udpServer: TUDP_Serv;
udpCl: TIdUDPClient;
bSnd, bRcv: TBytes;
s: string;
k: integer;
//==============================================================================
procedure TUDP_Serv.udpSvUDPRead(AThread: TIdUDPListenerThread; AData: TIdBytes;
ABinding: TIdSocketHandle);
begin
writeln(' Server read: ' + ToHex(AData, length(AData)));
with ABinding do SendTo(PeerIP, PeerPort, AData);
end;
//==============================================================================
begin
try
udpServer := TUDP_Serv.Create;
with udpServer do begin
OnUDPRead := udpSvUDPRead; DefaultPort := 20001; BufferSize := 2048;
ThreadedEvent := true; Active := True;
if Active then writeln('Server started on port: ' + IntToStr(DefaultPort));
end;
udpCl := TIdUDPClient.Create;
with udpCl do begin
BufferSize := 2048; Host := '127.0.0.1'; Port := 20001;
end;
SetLength(bSnd, 5); bSnd[0] := $31; bSnd[1] := $0;
bSnd[2] := $33; bSnd[3] := $0; bSnd[4] := $0;
repeat
writeln(' Client send: ' + ToHex(bSnd, length(bSnd)));
with udpCl do SendBuffer(Host, Port, bSnd); sleep(100);
try
k := udpCl.ReceiveBuffer(bRcv, 10);
if k > 0 then writeln(' Client read: ' + ToHex(bRcv, length(bRcv)));
except
on E: exception do begin
writeln(Format(' Client read err: %s',[E.Message]));
end;
end;
readln(s);
until s <> '';
except
on E: Exception do begin
Writeln(E.ClassName, ': ', E.Message); readln(s);
end;
end;
end.
屏幕输出:
Server started on prot: 20001
Client send: 3100330000
Server read: 3100330000
Client read err: Socket Error # 10040
Message too long.
答案 0 :(得分:0)
10040是WSAEMSGSIZE
,这意味着您尝试接收的缓冲区小于收到的邮件的实际大小。
在调用bRcv
之前,你没有为ReceiveBuffer()
分配任何内存,所以你试图接收到一个0字节的缓冲区,然后发现错误。您需要预先将bRcv
预分配到至少与邮件相同的大小(如果不是更大)。
ReceiveBuffer()
不会为每封收到的邮件分配新的TBytes
。您必须事先自己分配缓冲区,然后ReceiveBuffer()
将仅填充它,返回实际接收到的字节数。