关于socket接收数据的问题

iwillgo2 2003-08-22 11:22:25
我做了一个测试:
在Client端连续发送几个数据包:
ClientSocket1.SendText('12');
ClientSocket1.SendText('3456');
ClientSocket1.SendText('789');

在Server端接收:(在Read事件)
procedure TF_Server.Server1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
Mem_Send.Lines.Add(socket.ReceiveText);
end;

结果:
按照我的想法应该为:
12
3456
789

实际接收:123456789
假如我在发送的时候每一个SendText设断点,则收到的数据:
12
3456
789

我如何作才能使我正确收到的数据为:
12
3456
789
...全文
110 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
aiirii 2003-09-06
  • 打赏
  • 举报
回复
我试了下,要这样:
ClientSocket1.Socket.SendText('aaa'#13#10);
ClientSocket1.Socket.SendText('bbb'#0);
ClientSocket1.Socket.SendText('ccc');

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var s: string;
begin
s := Socket.ReceiveText;
Memo1.Lines.Add(S);
end;
yzykjh 2003-09-05
  • 打赏
  • 举报
回复
ClientSocket1.SendText('12'#13#10);
ClientSocket1.SendText('3456'#13#10);
ClientSocket1.SendText('789');
aiirii 2003-09-05
  • 打赏
  • 举报
回复
其实,自己处理可能是比较好的办法!
我在d6中试过,我以前好象看过个帮助,有个Api之类的,但刚才找了会,找不到,
试过加个#0,强制结束,但不行,
ClientSocket1.SendText('12'#0);
ClientSocket1.SendText('3456');

在D7中,一般会用IdTCPClient
其中就有IdTCPClient1.FlushWriteBuffer(-1);


power_yhb 2003-09-04
  • 打赏
  • 举报
回复
同意sunrains(流星)
其中最重要的几点.
1、定义自己的数据包格式。

2、由于网络质量的问题,要在接收端对系统数据包进行重新组合。

3、流技术的应用
aiirii 2003-09-04
  • 打赏
  • 举报
回复
记得有个强制发送的,但一时找不到,你用的是d7?d6?的那个控件???
chenyourkey 2003-09-03
  • 打赏
  • 举报
回复
怪不得我的传输接收也老是有问题
zhiwuyang602 2003-09-02
  • 打赏
  • 举报
回复
定义消息格式!
sunrains 2003-08-27
  • 打赏
  • 举报
回复
其实,如果用Socket做文件的传输,最好且可靠的方法是:1、定义一套通信协议;2、client和server采用一问一答的方式交互进行。
2312 2003-08-26
  • 打赏
  • 举报
回复
gz
myling 2003-08-23
  • 打赏
  • 举报
回复
晕。

在消息里胡说了一通,怎么被贴出来了?
猛禽 2003-08-23
  • 打赏
  • 举报
回复
其本上这种担心也是多余的,客户端的每个线程会对应服务端一个独立的线程,SOCKET会自动根据连接的不同,分开传输,不会乱的。
iwillgo2 2003-08-23
  • 打赏
  • 举报
回复
myling(阿德) 的回答,贴出来共享:

是否存在这种情况,接收端接收到四个包,包的顺序包1为线程1的数据,包2为线程2的数据,包3为线程1的数据,包4为线程2的数据,我怎么知道那两个包是线程1,那两个包是线程2的数据


是这样的,接受端不管是那个线程的,它只负责接受
接收到以后她只想知道是那个客户端发的

如果你说的这个是一个客户端,然后利用不同的线程来控制它发包
那么就按照线程发生的顺序,它会依次收到四个包,
但是是一个客户端发来的

线程其实就是利用CPU分时复用的原理,用不同的时间段来运行程序
说线程效率高,就在这里,它把运行时间分散到各个时间段里了
普通的程序要等到其他时间段运行完了,轮到他所在线程的时间段,
才运行,其他时间其实是在等待,这就是我们所说的主线程
用了线程,就是相当于在其它的时间段内运行,正好和主线程错开了
这样我们感觉是两个程序在同时运行

如果你的客户端在线程中,就想我前面说的,就是不同的副本
服务器还会收到四个包,但这是就是两个客户端发来的

你想判断是那个线程发的,只有加标示了
例如在包的前面或者后面加上这个线程的ID,

其实在网络传输中,也正是这么做的,不过他们的信息要复杂的多

renzy205 2003-08-22
  • 打赏
  • 举报
回复
我也有同样问题
catac 2003-08-22
  • 打赏
  • 举报
回复
我觉得不是接收的问题,是不是Mem_Send.Lines.Add(socket.ReceiveText);你用的是ADD是不是把三次接收的写在一行上了呀,
tiexinliu 2003-08-22
  • 打赏
  • 举报
回复
增加数据头XXX+yourdata,XXX用来标识数据长度,服务器端先判断XXX,然后接收.
thh820630 2003-08-22
  • 打赏
  • 举报
回复
在tcpsocket中传输数据时
它本身维护一个小于4K的缓冲区,如果你发送的大于4K,你就要分次发送,在接受端自己衔接起来.
你上面的问题是由于你在连续的调用发送函数时,是先向缓冲区写入然后再传出的,这就可能出现在第一个数据还没有传出,第二个又写进来了,计算机会把它当成一个传出,所以就会出现你的三个成一个字符串的形式.
为了避免,你可以采用一问一答的模式:
就是在客户端送出第一笔数据后,如果server受到了 就回一个确认信息,client再送出第二笔
mme 2003-08-22
  • 打赏
  • 举报
回复
setsockopt为TCP_NODELAY
猛禽 2003-08-22
  • 打赏
  • 举报
回复
呵,偶就不用回答了吧:)
iwillgo2 2003-08-22
  • 打赏
  • 举报
回复
myling(阿德) 的回答,贴出来共享:


假如数据很多的时候,处理起来岂不是很麻烦,还有一个问题,假如有一个完整的包,传送过程中把包给拆了,有两台这样的机器同时发数据给我时,我收到的数据岂不是很乱,我如何对数据进行再组织


其实可以存放到一个数组中,然后用sendbuf来传

至于你说的乱了的话可以放心,因为socket是面向连接的
服务器对不同的客户端,是不同的连接
在delphi里,是sockt.ActiveConnections[i]数组
连接不会发生混乱,delphi已经进行了封装
myling 2003-08-22
  • 打赏
  • 举报
回复
同意 Raptor(猛禽) 老哥

我在处理字符的时候一般是这样

ClientSocket1.SendText('12/3456/789');

然后收到以后根据‘/’来拆分


加载更多回复(2)

1,593

社区成员

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

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