ServerSocket/Clientsocket收发数据问题 请高手详解 200分(200分)

  • 主题发起人 主题发起人 yihui
  • 开始时间 开始时间
Y

yihui

Unregistered / Unconfirmed
GUEST, unregistred user!
在一个用serversocket和clientsocket的TCP/IP程序中

Server端ServerSocket.Socket.Connections[0].SendText(SomeString)

procedure TfrmMain.SendCmnd(CmndStr:string);
begin
serversocket.Socket.Connections[0].SendText(CmndStr);
end;


client端Socket.ReceiveText,根据接收的string不同执行不同的操作:

procedure TfrmMain.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var RcvTxt:string;
begin
RcvTxt:=Socket.ReceiveText;

if RcvTxt='CmndString1' then
begin
...
end;

if RcvTxt='CmndString2' then
begin
...
end;
...
end;


Server端执行SendCmnd()一次或几次执行的间隔时间大些,则在client端程序正常,
但是如果执行
...
SendCmnd(command1);
SendCmnd(command2);
SendCmnd(command3);
SendCmnd(command4);
...
那么Client端的程序就不正常了.如何解决?


 
在client端执行一条命令后给server端发个反馈信息如何?
server等收到反馈后再发下一条命令。
 
对执行完后发个反馈信息,
 
不正常是什么意思啊 不如自己跟一下 看接收到的Socket.ReceiveText是什么
也许是几个command和在一起了,如果是这种情况,你应该自己定义一个“命令帧”的格式
加上标识一个命令的边界字符或特征。
 
SendCmnd(command1);
SendCmnd(command2);
SendCmnd(command3);
SendCmnd(command4);
你连续发送,则client端收到的应该是 command1+command2+command3+command4
或他们的一个组合,而不一定是一个单独的commandx.所以同意g622的方式,使
用边界字符,或者干脆自定义数据帧
 
tasam的方法简单易用。
 
用线程处理接受。
 
这个线程也不能解决,的确有这个问题,数据包的切割不是你自己控制的。

虽然 tasam的办法很简单,但是他也可能出现一个commandx被切割的问题,这样你又无法判断了。
不过这是理论上的,我也类似tasam的办法写过程序,目前没出现过问题。

专业的办法你应该自己定义数据格式,然后建一个buffer,把收到的东西写入buffer,然后查找。

这样的问题,在写串口的时候也有。
 
我也碰到过类似的情况,我的处理方法和tasam一样,在收到之后返回一个确认信息,然后服务
器再发第二条命令.
 
大致的思路已经明了,谢谢大家!
puzzle,专业的办法你应该自己定义数据格式,然后建一个buffer,把收到的东西写入buffer,然后查找
能不能给个例子?
 
很抱歉,我现在没有这样的例子,但我可以告诉你具体思路。
1,为每个连接建立一个buffer,
2,每次接收到数据后你就把他添加到buffer最后面,
3,然后从buffer开始检查是否出现了你的那个command字符串,
4,如果出现了,执行你相应的程序,然后删除包括commadn字串之前的buffer(认为处理完毕,没必要保留了)。

这就是大概的接收数据事件的过程。

查找的算法看你buffer的定义了,如果你接受都是字符串,那么用string作buffer, pos查找很方便。
如果是bin数据,那么建议用array of byte了。然后自己写一个查找,这样的算法在大学数据结构里面有详细的介绍。

这个找的思路就是把没次接受的小buf,和并成为一个大大的buffer,这样避免了数据备分割。
 
To:yihui,我写过这样的程序,你去看看吧!
程序:http://www.bitelong.com/soft/client.exe
源码:http://www.bitelong.com/soft/picqcode.zip
 
server:

use socket.lock;

...
 
我贴上来算了!
将SendCmnd改为:
procedure TForm1.SendCmnd(CmndStr:String);
begin
serversocket1.Socket.Connections[0].SendBuf(CmndStr, Sizeof(CmndStr));
end;
客户端:
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
S: String;
begin
Socket.ReceiveBuf(S, Sizeof(String));
Memo1.Lines.Add(S);
end;

 
to silicon,
Lines.Add()是要在后面自动加换行的。
 
不管怎么样!取出的S就是要的串了!发什么叫到就是什么,而不是连在一起。
 
应该能运行啊。
 
后退
顶部