救急!!!IdTCPClient的readln问题,不能读全数据

学无止境w_y 2007-09-01 03:00:59
简单代码示意如下:

如果用
sResponse := IdTCPClient1.ReadLn;
则数据读不全,读出的数据是
#1#4#0#1#0#1#0'@j4譎'#8'傆O '#$A8

如果用
setlength(sResponse,64);
IdTCPClient1.ReadBuffer(sResponse[1],64);
则可以读全,但是这里是写死了读取64个字节,怎么样才能读全部服务端返回的数据呢?
全部数据是:#1#4#0#1#0#1#0'@j4譎'#8'傆O ?'#$A'僑漃'#$10'??S?\{?'#$11'技縗{?'#$11'技縗{?'#$11'技烤>eQ陣?'

注:此是客户端代码,服务端是由VC编写的
...全文
708 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq289429972 2009-01-13
  • 打赏
  • 举报
回复

接受端sResponse := IdTCPClient1.ReadLn(enUTF8);
qq289429972 2009-01-13
  • 打赏
  • 举报
回复

接受端sResponse := IdTCPClient1.ReadLn(enUTF8);
学无止境w_y 2008-10-29
  • 打赏
  • 举报
回复
貌似这个问题还没解决,呵呵
僵哥 2008-06-05
  • 打赏
  • 举报
回复
不要使用readln,实际上这是一个以换行符分割的一个简单文本传输协议。建议使用write(TStream,...)并且最后的参数指定需要发送size,接收端也一样,使用stream接收,并且接收size,这样子对于其他开发工具开发的程序也比较方便,就是对于小数据,最前面就是一个4字节,表示后续实际内容的长度,按规则接收即可。
柔情剑客 2008-06-05
  • 打赏
  • 举报
回复
顶起!阿胡同志我也姓胡。呵呵。我现在也遇到这个问题:QQ:282567546。能上线看到加我。谢谢了。
dabaicai 2007-09-04
  • 打赏
  • 举报
回复
客户端的接收数据工作本身就要放在线程里面(因为服务器可能不止发一次)
用ReadBuffer就可以实现
学无止境w_y 2007-09-03
  • 打赏
  • 举报
回复
首先谢谢空白的历史1966至1976的热心帮助!通讯协议是不可能改了,因为服务端不是由我开发
后来我是这样写的,暂时工作正常,不知道会不会有问题,
IdTCPClient1.WriteBuffer(str[1],Length(str));
IdTCPClient1.ReadFromStack;//加上这句后,下面的IdTCPClient1.InputBuffer.Size才会有值,否则是0,我用的是indy 9,如果是indy10的话不知道是不是就不需要这句了呢
i1 := IdTCPClient1.InputBuffer.Size;
IdTCPClient1.ReadBuffer(sResponse[1],i1);
numbbb 2007-09-01
  • 打赏
  • 举报
回复
最好修改一下通讯协议,先发送一个4字节的数据长度
i1:integer;

IdTCPClient1.WriteBuffer(str[1],Length(str));

i1:=IdTCPClient1.ReadInteger();

setlength(sResponse,i1);
IdTCPClient1.ReadBuffer(sResponse[1],i1);



线程轮询代码,只是用来说明问题,很多细节没有处理,用的是indy10
procedure nthread.Execute;
var
RecvCount : integer;
begin
while (True) do
begin
if self.Terminated then exit;
Sleep(1);
try
try
//是否有数据,非阻塞式
RecvCount:=self.IdTCPClient.IOHandler.InputBuffer.Size;
if (RecvCount>0) then
begin
//有数据
//从网络接收数据
with self.IdTCPClient.IOHandler.InputBuffer do
begin
ExtractToBytes(RecvBuffer,RecvCount,false);
end;
//清除缓冲
self.IdTCPClient.IOHandler.InputBuffer.Clear;
end;
except
//错误,跳过发送
Continue;
end;
end;
学无止境w_y 2007-09-01
  • 打赏
  • 举报
回复
回5楼:必须要另开一个线程收数据吗?
这样写可以吗?
IdTCPClient1.WriteBuffer(str[1],Length(str));
setlength(sResponse,64);
IdTCPClient1.ReadBuffer(sResponse[1],64);

以上代码是服务端返回字节是64的时候是可以正常工作的,但是需要写死读取的字节数。

如果用线程轮寻的话,可否提供一下示例代码,谢谢
numbbb 2007-09-01
  • 打赏
  • 举报
回复
通常情况下都是先用ReadBuffer收一个固定长度的报文头, 报文头里说明还剩下多少字节,然后继续收就可以了。

你这种情况只能在一个线程里轮询InputBuffer.Size,如果不为0,就用ReadBuffer收数据即可。
学无止境w_y 2007-09-01
  • 打赏
  • 举报
回复
回2楼: 服务器端没有约定数据包大小,因为大小不固定,也没有约定数据包结尾的标志,这里只是想用IdTCPClient一次读出全部服务端返回的数据

回3楼:IdTCPClient.IOHandler.InputBuffer.Size好像不对呀,IOHandler没有InputBuffer属性啊,如果改成IdTCPClient.InputBuffer.Size,则值是0,我的开发环境是delphi7。
numbbb 2007-09-01
  • 打赏
  • 举报
回复
先取得缓冲里数据的个数,然后再ReadBuffer
RecvCount:=self.IdTCPClient.IOHandler.InputBuffer.Size;
budded 2007-09-01
  • 打赏
  • 举报
回复
双方约定协议就可以了,
服务器端约定数据包大小了么?或者约定数据包结尾的标志了么?
学无止境w_y 2007-09-01
  • 打赏
  • 举报
回复
没有人回答吗?

1,593

社区成员

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

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