tcpclient 必须与tcpserver必须结合应用? ( 积分: 100 )

  • 主题发起人 主题发起人 hhxxj
  • 开始时间 开始时间
H

hhxxj

Unregistered / Unconfirmed
GUEST, unregistred user!
最近开发一个程序,客户端用delphi开发,服务端用VC6.0开发,客户端用的是delphi带的TCPCLIENT,给服务端发送数据服务端能收到,但是服务端给我反馈的信息要很久才能收到,不知是什么原因?难道是VC的SOCKET与DELPHI的步兼容?
其中部分代码如下:

TcpClient2.RemoteHost:= inttostr(JvIpAddress2.Address);
TcpClient2.RemotePort:='6001';

if not TCPClient2.Connected then
begin
MessageDlg('连接台情数据库服务器失败,请重新连接!',mtInformation,[mbOK],0);
abort;

end
else
begin
Commandstr:='SWTODB_LOGN';
strMessage:='@'+Commandstr;
strtemp:=edit1.Text;
strMessage:=strMessage+'U'+strtemp;
strtemp:=edit2.Text;
strMessage:=strMessage+'P'+strtemp;
strMessage:=strMessage+'$';
TCPClient2.Sendln(strMessage); //这里服务端能收到数据
sleep(200);
tempstr:=TcpClient2.Receiveln(); //这里程序就会停止半天不动
end;

哪位能具体说说tcpclient 是如何接收信息的?有时候为什么会收到空消息呢?
 
最近开发一个程序,客户端用delphi开发,服务端用VC6.0开发,客户端用的是delphi带的TCPCLIENT,给服务端发送数据服务端能收到,但是服务端给我反馈的信息要很久才能收到,不知是什么原因?难道是VC的SOCKET与DELPHI的步兼容?
其中部分代码如下:

TcpClient2.RemoteHost:= inttostr(JvIpAddress2.Address);
TcpClient2.RemotePort:='6001';

if not TCPClient2.Connected then
begin
MessageDlg('连接台情数据库服务器失败,请重新连接!',mtInformation,[mbOK],0);
abort;

end
else
begin
Commandstr:='SWTODB_LOGN';
strMessage:='@'+Commandstr;
strtemp:=edit1.Text;
strMessage:=strMessage+'U'+strtemp;
strtemp:=edit2.Text;
strMessage:=strMessage+'P'+strtemp;
strMessage:=strMessage+'$';
TCPClient2.Sendln(strMessage); //这里服务端能收到数据
sleep(200);
tempstr:=TcpClient2.Receiveln(); //这里程序就会停止半天不动
end;

哪位能具体说说tcpclient 是如何接收信息的?有时候为什么会收到空消息呢?
 
据说有点不同的,需要调整一下,只知道这么多,呵呵
 
一般客户端收到数据应该是多久啊?
 
可能是数据小的原因吧
tcp有个缓冲区
1》时间到了
2》数据满了
才会触发事件
 
谢谢两位的解释
再问问:

是不是要接受服务器发回的信息,必须调用一次TcpClient.Receiveln;

然后才能触发onReceive事件。因为它不象ClientSocket自动检查接收缓冲区。

但是我那个也调用了,但是就停着不动了,是不是就是小猪说得
tcp有个缓冲区
1》时间到了
2》数据满了
才会触发事件
这样的话能不能改一种方式呢?
 
无论是哪种语言,其Socket处理机制都是一样的,你说你的程序很长时间才能收到消息,那可能是因为服务器端接受你的消息后要进行处理,可能是处理的时间长,并不是VC的SOCKET与DELPHI的不兼容。
 
TcpClient.Receiveln;
遇到回车才能返回的,或者有足够多的数据才能返回,
否则,一直阻塞状态
都是用的Socket API ,是用法不对
 
to wanghaiou
嗯后来经过验证的确像你所说,不是DELPHI和VC之间的兼容性造成的,但是也不是因为服务器处理时间太长造成的,而是别的原因造成,也许就像lich所说的一样,“TcpClient.Receiveln;遇到回车才能返回的,或者有足够多的数据才能返回,
否则,一直阻塞状态”
这句话偶不知道其正确性,不过的确有些像,因为用Receiveln的时候出现过那样的字符,
但是偶后来结合TCPCLIENT的onreceive事件后就可以了,所以还是不理解
如果lich能再解答一下,偶感激不尽
 
应该是等待超时吧和数据满吧
 
那么什么情况才算是满呢?
 
TCPClient2.Sendln(strMessage); //这里服务端能收到数据
sleep(200);
tempstr:=TcpClient2.Receiveln(); //这里程序就会停止半天不动
我不明白这么写是什么意思,你是想让tempstr等于服务器返回的消息吗?
如果是那样的话,你应该把tempstr:=TcpClient2.Receiveln(); 要实现的功能放到TcpClient的OnReceive事件里面才对。
 
to wanghaiou:
是的,偶后面是按照你的方法做了,目前是对的,但是偶发现当和服务器连接上等待服务器返回信息时,当服务器出错时,就会收不到信息,这时就没法跳出来了,不知道有什么方法能判断出错了呢, ONERROR事件似乎太宽了,连正常断开也会响应,能给个提示嘛?


tempstr:=TcpClient2.Receiveln(); //这里程序就会停止半天不动
这样写程序的确就不动, 要直接TcpClient2.Receiveln(); ,然后在到ONRECEIVE事件中去活得数据却是可以的, 到底时什么原因呢
 
你要是这么写大概也可以
while 1=1 do
begin
tempstr:=TcpClient2.Receiveln(); //这里程序就会停止半天不动
sleep(1000);
end;
这样也是每隔一段时间看看有没有消息发过来,不过这样写也有很多弊病。
而在他的ONRECEIVE写处理过程是最好的,因为每当客户端受到一条信息的时候就会触发一次这个事件。
至于出错处理最好还是写在OnError事件里面,在这个事件的最后写上 SocketError:=0;
看看是不是会有意想不到的收获!
 
要看是阻塞方式还是非阻塞方式,
两者的编程模型是不一样的,
程序的处理方式是完全不同的
 
偶应该采取的是非阻塞模式的,因为采取了阻塞模式后就连不上了服务端了, 可能对方就设定的是非阻塞的吧。
经过学习自己也是在TCPCLIENT的onreceive事件中来处理来自服务端的消息,好像没问题了,但是今天发现接到长的数据时又出现了问题了,主要是这个函数:
procedure Tloginfrm.TcpClient2Receive(Sender: TObject; Buf: PAnsiChar;
var DataLen: Integer);
当对方发一堆数据时, 自己却只能收到一段, 而不是全部,但是数据长度却是正确的
这里想问这里的buf收到的到底是多长的数据?
又或者有没有更好的方式来接收来自服务端的数据,服务端是定义了一个结构然后把值分别付给结构后再发送过来,偶用的是TCPCLIENT控件,在不改变这个控件的情况下 偶应该怎么样做,怎么才能一次完全接收到服务器一次发来的数据呢?
 
如果想在不同的语言之间传送一个结构还是要仔细考虑一下。毕竟delphi和c++有很大的不同。
 
现在还是用DELPHI5带的那个clientsocket了,INDY也不好用,阻塞式有时候真的不好用,结束问题吧!
 
后退
顶部