DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: lixuan123
今日帖子: 0
在线用户: 3
导航: 论坛 -> 网络通讯 斑竹:liumazi,sephil  
作者:
男 ds3000 (ds3000) ▲▲▲▲△ -
普通会员
2020/12/14 16:11:29
标题:
关于Indy的TIdUDPClient接收数据求助 浏览:2369
加入我的收藏
楼主: 最近几天调试UDP通讯,所以想写个UDP的工具软件,服务器端的通讯没问题,但是客户端通讯老是出问题,刚开始的出现卡死状态,卡死状态解决后,现在读数据又出现问题:

procedure TMainFrm.Timer1Timer(Sender: TObject);
var
  iLen: Integer;
  ABuf: TIdBytes;
begin
  try
    //IdUDPClient1.BroadcastEnabled := True;
    iLen := IdUDPClient1.ReceiveBuffer(ABuf, -1);
    if iLen < 1 then Exit;

    AddRecv(IdBytesToAnsiString(ABuf));
  except
    on E:Exception do
    begin
      AddInfo('Information:  ' + E.Message);
    end;
  end;
end;

上面是个TTimer来间隔读数据,运行报异常:
此帖子包含附件:
PNG 图像
大小:9.0K
----------------------------------------------
-
作者:
男 ds3000 (ds3000) ▲▲▲▲△ -
普通会员
2020/12/14 16:12:58
1楼: 求助:这个问题应该怎么解决?
----------------------------------------------
-
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2020/12/14 16:15:07
1楼: UDP 数据包不能大于64K
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 ds3000 (ds3000) ▲▲▲▲△ -
普通会员
2020/12/21 16:25:39
2楼: 没有这么大,就1234几个数字,在测试中。TIdUDPClient的默认BufferSize是8192
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2020/12/21 16:33:28
3楼: 你用 Timer 来读数据本身就不对。

IdClient 是阻塞读。如果不想把程序冻结,就应该用一个线程来读。

其实我是想要告诉你,用 IdUDPClient 稍微麻烦了。不如直接用 IdUDPServer。

是的,服务器和客户端,两头都可以用 IdUDPServer。
----------------------------------------------
-
作者:
男 ds3000 (ds3000) ▲▲▲▲△ -
普通会员
2020/12/21 16:37:18
4楼: 找到原因了,是ABuf变量问题,我对ABuf使用了SetLength就OK了。

procedure TMainFrm.Timer1Timer(Sender: TObject);
var
  iLen: Integer;
  ABuf: TIdBytes;
begin
  try
    SetLength(ABuf, 8192);

    IdUDPClient1.BroadcastEnabled := True;
    iLen := IdUDPClient1.ReceiveBuffer(ABuf, 100);
    if iLen < 1 then Exit;

    AddRecv(IdBytesToAnsiString(ABuf));
  except
    on E:Exception do
    begin
      AddInfo('Information:  ' + E.Message);
    end;
  end;
end;
----------------------------------------------
-
作者:
男 ds3000 (ds3000) ▲▲▲▲△ -
普通会员
2020/12/24 11:20:03
5楼: to: pcplayer

谢谢!这个方法我也试过,客户端如果用 IdUDPServer 控件,打开和发送数据都没有问题,但是接收数据收不到,比如:服务器端我用 IdUDPServer1 打开 10000 这个端口进行监听,客户端我用 IdUDPServer2 打开 20000 这个端口来进行监听,客户端发送可以指定 IP 和 Port 进行发送,但是客户端因为开的是本地端口 20000,所以收不到服务器 IdUDPServer1 发送的数据。 也可能是我对这二个控件理解的不够透,试了一下没成功,因为赶时间用,所以改用Timer来操作。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2020/12/24 17:24:41
6楼: 你的服务器端和客户端是对等的呀。两边使用相同的控件,怎么可能一边能收到,一边收不到?

我觉得你可能是服务器端发送给客户端的数据,IP / PORT 没搞对。

你服务器端收到数据,要检测到客户端的 IP/PORT,然后从这个 IP/PORT 发回去。

如果是局域网,你的服务器端打开 10000 监听,收到的来自客户端的数据,应该是客户端的 IP 和 20000 号这个端口。你发送回去就要发这个 IP/PORT。

简单说,一个 IdUDPServer 在 OnRead 事件里面,要知道数据来自哪里(也就是对方的 IP/PORT):

procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
  ABinding.PeerIP
  ABinding.PeerPort
end;

如果要发送数据回去给对方,就按照上面的 PeerIP / PeerPort 作为目的地址来发送。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2020/12/24 17:28:34
7楼: 楼上说的对。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 ds3000 (ds3000) ▲▲▲▲△ -
普通会员
2021/1/5 17:27:48
8楼: to  pcplayer:
测试成功了,谢谢!
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行69.82422毫秒 RSS