关于使用IdTcpServer与VC通信丢包的问题(100分)

  • 主题发起人 主题发起人 menye
  • 开始时间 开始时间
M

menye

Unregistered / Unconfirmed
GUEST, unregistred user!
我用IdTcpServer与VC通信,每次根据客户端(VC)的请求,数据库中查询数据,按照定义好的
的数据结构一条一条的发送给客户端,如果是数据很少的情况(4,5条)数据传输没问题,但是
一旦数据达到几千条数据时,就会发生数据丢包现象,
现在我就在发送的数据结构后加一个校验的数据位,服务器端发送数据,客户端接收数据,
根据校验位检验数据是否正确,错误,返回错误信息,服务器重新发送。正确就发送下一条数据
基本上就能解决问题,但是如果采取校验的方法,数据的传输速度很慢的,每发送一条数据,就得
等待客户端的校验信息,
我想知道各位有什么更好的方法了,大家交流一下
 
怎么没人看了,^_^
 
如果用TCP,不可能出现丢包,一定是你程序谋个地方有问题
 
我在用delphi和java用socket通信的时候,有时候会出现无法传送数据的现象。
并且就算是能够传送数据,接受到的都是错误的。
兄弟能不能给点意见
 
我现在是可以传输数据,就是数据量一大 ,就会发生客户端接收的数据错误,我现在是加一个
校验位,检测是否错误,如果错误,重复发送。
在我的映象中,tcp应该不会出现这个问题的,
 
同意 sofox,是你程序的问题,我做过很多类似的开发,
同时发送好几百M的数据都没有问题,是你控制的不好
不要怪TCP了
 
以下是我的程序的大概框架:
//数据结构iResPopluation赋值
。。。。。。
//发送数据
Thread.Connection.WriteBuffer(iResPopluation,Sizeof(iResidentPopluation));
//等待客户端的返回确认信息
while AThread.Connection.Connected do
begin
AThread.Connection.ReadBuffer(ResultInfo,5);
str := Trim(ResultInfo);
if str <> 'succe' then //如果数据错误,就重发
AThread.Connection.WriteBuffer(iResPopluation,Sizeof(iResidentPopluation))
else
Break;
end;

if not AThread.Connection.Connected then Exit;
//如果照片大小大于0,就发送相片
if iResPopluation.PictureSize >0 then
begin
TempStream := TMemoryStream.Create;
AThread.Connection.OpenWriteBuffer();
AThread.Connection.WriteStream(TempStream);
AThread.Connection.CloseWriteBuffer ;
end;

finally
TempStream.Free ;
TempStream := nil;
end;
except

end;
end;

各位,看看,有什么不妥的地方请指出来,谢谢^_^
 
首先我不知你在vc中使用了阻塞模式还是非阻塞模式
因为IdTcpServer是阻塞模型的socket,所以在客户端最好使用
阻塞模型,当然非阻塞也可以,不过你要控制的地方就越多
 
Server和Client根本就没有都用同一种模式,组塞和非组塞只是你控制缓冲的一种模式
和TCP根本无关,你丢包是你控制的不好,错误错误的方式有问题
 
to:CODEHUNTER
服务器和客户端都是阻塞的,有时发送的数据是好的,有时就是错误的,
to:张无忌
老大,我想问一下,我在上面贴的那段代码问题出在什么地方(服务器端的),能否说的
清楚些,谢谢^_^
 
to 楼主,想问两个问题,看来你解决啦,不胜感激
1 IdTcpServer如何发信息到IdTcpClient?,在IdTcpClient如何获取Server发的信息?
2 如果我用多线程或TIMER控件取得信息,服务器端没法正常退出,报thread termate timeout

麻烦你一下,不好意思。
 
to xzh2000
1.IdTcpClient先根据服务器的地址和端口和IdTcpServer建立连接,IdTcpServer就可以使用以write开头的方法向客户端发送消息,IdTcpClient用以read开头的方法读取服务器端发来的数据
2。如果使用IdTcpServer控件编写服务器端的话,并且采用阻塞的方式,见以下例子:
procedure TfrmMain.IdTCPServerExecute(AThread: TIdPeerThread);
var
cliProtocol: ClientProtocol;
serProtocol: ServerProtocol;
begin
AThread.FreeOnTerminate := True;
with AThread.Connection do
begin
//读取客户端的请求
ReadBuffer(cliProtocol,sizeof(ClientProtocol));
AThread.Synchronize(IncrConnectionCount);
、、。。处理客户端的请求
//发送数据到客户端
WriteBuffer(serProtocol,Sizeof(ServerProtocol));
end;
end;

服务器端接到客户端的请求后,处理的过程全部在事件Execute中执行
 
Server 没有做同步控制啊,小兄弟

CS: TCriticalSection

var
sRcv, sCommand, sParam: string;
begin
CS.Enter;
try
//接收客户端请求和回应客户端请求
//你在此处写的程序框架有问题,基本上这样写就可以啦
sRcv := Uppercase(AThread.Connection.ReadLn);
sCommand := copy(sRcv, 1, 5);
sParam := copy(sRcv, 5, Length(sRcv) - 5);
if sCommand = 'LISTS' then
begin
//进行相关列表处理....
AThread.Connection.WriteLn('处理结果');
end
else if sCommand = '其它命令' then
....
except
on E: Exception do
ShowMessage(E.Message);
end;
CS.Leave;
end;

 
另外与客户端是阻塞与非阻塞与通信是没有什么关系的,就是说,你客户端可以随便使用任何方式,不会产生任何通信问题。
 
陈兄:
我现在是使用一个客户端连接进行测试,应该不存在线程同步的问题了,在说明一下,客户端是在WINCE环境下运行的,WINCE使用的是unicode,会不会是这个原因了,请指教
 
wince只支持WINSOCK1,估计是对方的问题把
 
谢谢各位了,我想原因可能是张兄说的,结帐了^_^
 
后退
顶部