关系 TIdTCPServer 的中 Socket.Readstring() 的长度问题;

aroc_lo 2014-06-20 05:25:32
我有一硬件,通过 TCP/IP协议主动的发送心跳包到 指定的 IP。。。

正常数据类似:

beats,count=3768,type=10,name=TN_1e306c2b5727,machine_no=8888,ip=10.1.153.31,now_time=2014-06-20_17:09:02,white_name

(长度不定,上面的长度为 116)

我用TIdTCPServer组件来获取 TCPIP传来的数据
代码如下:



procedure TForm1.TS_1Execute(AContext: TIdContext);
var
s:string;
_cmd : string;
len:Integer;
begin
// len :=AContext.Connection.IOHandler.RecvBufferSize ; //这个得到的长度是0
// len :=AContext.Connection.IOHandler.InputBuffer.Size ; //这个得到的长度是32783

with AContext.Connection do begin
s := IOHandler.ReadString(116); //这个长度很让人难搞,这里不能使用 Len的值、、
// IOHandler.InputBuffer.Clear; //如果使用这个,则会间隔性的丢失数据。。即:只能收到 1.3.5.7.9 的数据 2.4.6.8.10 ...等则丢失)
MM_1.Lines.Add(FormatDateTime('hh:mm:ss.zzz'+#13#10,Now)+s) ;
_cmd := Copy(s,1,5);
if (Trim(_cmd)='beats') or (_cmd[1]='0') then begin
Socket.WriteLn(' ',enUTF8);
MM_1.Lines.Add('回复空格') ;
end;
end;



问题就来了,,假如我一直是 IOHandler.ReadString(116); 这里一直是 116,那么收上面的那些数据,没有问题;
可是问题在于。那长度并非固定的是 116

现在我改成 IOHandler.ReadString(117); //将116改成了117

那麻烦就来了,,
第一次读取上面的字串(正确)
beats,count=3768,type=10,name=TN_1e306c2b5727,machine_no=8888,ip=10.1.153.31,now_time=2014-06-20_17:09:02,white_name
第二次读取时就少了,变成:
eats,count=3768,type=10,name=TN_1e306c2b5727,machine_no=8888,ip=10.1.153.31,now_time=2014-06-20_17:09:02,white_name (第一个 b 不见了,即第一次字符没有了)
第三次
ats,count=3768,type=10,name=TN_1e306c2b5727,machine_no=8888,ip=10.1.153.31,now_time=2014-06-20_17:09:02,white_name (第一、二个不见了,即前两个字符没有了)
以些类推。

假如我改成 IOHandler.ReadString(120); //将116改成了 120
第一次读取上面的字串(正确)
beats,count=3768,type=10,name=TN_1e306c2b5727,machine_no=8888,ip=10.1.153.31,now_time=2014-06-20_17:09:02,white_name
第二次读取时就少了,变成:
s,count=3768,type=10,name=TN_1e306c2b5727,machine_no=8888,ip=10.1.153.31,now_time=2014-06-20_17:09:02,white_name (前 次数*(120-116)=1 * 4 = 4 个字符不见了)
第三次
unt=3768,type=10,name=TN_1e306c2b5727,machine_no=8888,ip=10.1.153.31,now_time=2014-06-20_17:09:02,white_name (前 次数*(120-116)=2 * 4 = 8 个字符不见了)
以些类推。


也就是说,,那个 长度必须正确,否则就不能读出正常的数据;

假如我改成 IOHandler.ReadString(110); //将116改成了 110,

则第一次只能读110个字符。第二次,就把坊取 6个字符。。第三个就乱七八槽(具体是什么就没有分析了,反正是不正确的)

我现在该怎么办。。


另:
TSocketServer 这个组件能很好的读取数据。

但是。这个组件不支持 Unicode (因为我要返回中文到机器),
...全文
695 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
lyhoo163 2015-04-11
  • 打赏
  • 举报
回复
看上去,好样返回的字符串在内存中,与Delphi存贮方式不一样。出现偏移。
蓝色光芒 2015-04-11
  • 打赏
  • 举报
回复
应该是n + Length('white_name')-1
蓝色光芒 2015-04-11
  • 打赏
  • 举报
回复
var
  S , sBuf : String;
  n : integer;
begin
  ...
    S := IOHandler.ReadString(1024);   //用一个足够大的
    sBuf := sBuf + S;
    //这里来分析sBuf,只处理并删除一个完整的内容,剩余的内容,让下一条数据补充
    //比如假设一行的内容是beats,count=3768,type=10,name=TN_1e306c2b5727,machine_no=8888,
    //ip=10.1.153.31,now_time=2014-06-20_17:09:02,white_name
    //我假设'white_name'是行结束标记
    while True do begin
      n := Pos('white_name' , sBuf);
      if n=0 then Break;
      S := Copy(sBuf , 1 , n + Length('white_name'));
      Delete(sBuf , 1 , n + Length('white_name'));
      //这里S就是一行数据了
      //........
    end;
  ....
end;
limiao1975 2015-04-11
  • 打赏
  • 举报
回复 1
IOHandler.ReadBytes(bs, -1, False); if Length(bs) > 0 then ss := BytesToString(bs);
aroc_lo 2014-06-21
  • 打赏
  • 举报
回复
自己up一下
aroc_lo 2014-06-20
  • 打赏
  • 举报
回复
自己up一下

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧