socket编程的问题,大家都来看看

xwy1982 2005-06-22 11:34:39
服务器端:
int itemlen=ListBox1->Items->Count;
int m=ServerSocket1->Socket->ActiveConnections;
for(i=0;i<=itemlen;i++)
{
AnsiString sdata1=ListBox1->Items->Strings[i];
AnsiString sdata2=ListBox2->Items->Strings[i];
Label2->Caption=sdata2;
int sdata1len=sdata1.Length();
AnsiString sdata=IntToStr(sdata1len)+sdata1+sdata2+"@online@@";
ServerSocket1->Socket->Connections[m-1]->SendText(sdata);
}


客户端:
AnsiString Data=Socket->ReceiveText();
AnsiString SubData1=Data.SubString(Data.Length()-8,Data.Length());
if(SubData1=="@online@@")
{
Label5->Caption=Data;
Label6->Caption=Data.Length();
int olLen=StrToInt(Data.SubString(1,1));
AnsiString ol=Data.SubString(2,olLen);
Label3->Caption=ol;
AnsiString olip=Data.SubString(olLen+2,Data.Length()-10-olLen);
Label4->Caption=olip;
}

为什么当服务器端的listbox有多行数据时,发给客户端的数据会一只叠加上去,也就是变成这样的格式3xxx127.0.0.1@online@@3ccc127.0.0.1@online@@
当只有一个数据时就正常了,就是3ccc127.0.0.1@online@@这样能正确分析了

不是说当收到新的数据时会把旧的清空吗,我该怎么办啊?
...全文
404 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
zyyoung 2005-07-06
  • 打赏
  • 举报
回复
在第二次发信息时,前面加上
Sleep(900);
FengSC 2005-07-04
  • 打赏
  • 举报
回复
发送回复信息是很好的办法,一定能很好的实现。
heartpartee 2005-07-04
  • 打赏
  • 举报
回复
如果client的连接数特别多的时候又怎么处理呢?
痞子酷 2005-06-29
  • 打赏
  • 举报
回复
数据要多大才会分开发:主要由IO缓冲区和时间来决定的。


你看看可不可以flush缓冲区试试。呵呵~~~
痞子酷 2005-06-29
  • 打赏
  • 举报
回复
呵呵:
是否碰到过读取的信息是这样的:
3xxx127.0.0.1@online@@3ccc127.0.0.1@onl
后面的信息还没有过来。
你又该怎么办理呢?
socket通信我从来不喜欢用控件,一般直接采用SOCKET API来完成。
读取数据控制自如。可以一个一个去读,也可1K1K去读,很方便。


jishiping 2005-06-28
  • 打赏
  • 举报
回复
这个没有确切的数字,和操作系统以及系统的设定有关。如果是局域网,1K以内的数据,一次应该都可以发送完的。
xwy1982 2005-06-28
  • 打赏
  • 举报
回复
数据要多大才会分开发
54thb 2005-06-27
  • 打赏
  • 举报
回复
如何判断是一次发送完还是多次发送完?
jishiping 2005-06-27
  • 打赏
  • 举报
回复
不过我自己也想到一个,把所有的数据一次性按格式发出去。
------------------------------------------------------
虽然你是调用一次函数发出去的,如果数据很多,一次只会发送部分数据。至于发送出去了多少,可以通过SendText的返回值知道。即使一次全部发出了,但是还是不能保证接收端也能一次全部接收下来。所以,程序必须要能对多次接收的数据做处理。如果你能确保每次发送的数据比较少,那么发送和接收才会都市一次完成。
xwy1982 2005-06-27
  • 打赏
  • 举报
回复
FengSC(猪)的办法不错,有空去试试
jishiping(JSP 季世平) 真是大好人,真的帮我写

不过我自己也想到一个,把所有的数据一次性按格式发出去。
jishiping 2005-06-24
  • 打赏
  • 举报
回复
客户端:

在 Form 的class中,增加一个变量 AnsiString RcvText; 接收的代码如下:

RcvText += Socket->ReceiveText();
while(true) {
int nPos = RcvText.Pos("@online@@");
if (nPos == 0) break;

AnsiString Data = RcvText.SubString(1, nPos+8);
RcvText.Delete(1, nPos+8);

// 这儿的 Data,就是服务器端每次发送的字符串,下面增加你处理的代码
}
FengSC 2005-06-24
  • 打赏
  • 举报
回复
我有一个最简单有效的方法,发送端发完一个包的数据后等待接受,收到“OK”后再开始发送下一个包。接收端收到一个包的收据后发送“OK”到服务端。够简单吧。
jishiping 2005-06-23
  • 打赏
  • 举报
回复
办法很多,一个办法,先发送长度(2个或者4个字节,二进制的WORD或者DWORD),然后根据长度读取制定长度的字节。

或者根据自己的格式来处理。比如,你这儿的数据,每一行数据后加@online@@,那么你收到数据后,使用循环,查找@online@@,如果找到了,就取出@online@@前面的字符,然后将这些字符从字符串中删除,再次查找@online@@。如果查找不到@online@@了,但是字符串中还有剩余的字符,那么就先放在那儿,下次收到字符串后,再添加到这个字符串后,然后再按照上面的办法来处理。
xwy1982 2005-06-23
  • 打赏
  • 举报
回复
我发现是不稳定,但到底是服务器端不稳定,还是客户端不稳定还不清楚
因为我测试了一个最简单的。
谁知道这是什么原因,有什么办法解决
xwy1982 2005-06-23
  • 打赏
  • 举报
回复
谢谢楼上两位
但是还是不懂怎么解决,因为发送的包的长度是不定,我尝试最后加两位表示包的长度,可是发送的时候也不是完整的多个包粘一起,会出现截断的情况,这样就判断不了了
两位有没什么好的方法
有没办法强制服务器端发送数据,不要等缓冲区满
jishiping 2005-06-23
  • 打赏
  • 举报
回复
简单一点的道理,Socket 的发送和接受,系统是有缓冲的。也就是说,你多次发送的小数据,在接收端,可能只要一次就接收完了。你一次发送大数据(有个几十KB就看出来了),在接收端可能需要多次才能接收完。发送和接收,不是一对一的关系。
mmking33 2005-06-23
  • 打赏
  • 举报
回复
补充一些理论
http://www.vckbase.net/document/viewdoc/?id=1203
xwy1982 2005-06-23
  • 打赏
  • 举报
回复
好复杂,能不能帮我写一个
songykai 2005-06-23
  • 打赏
  • 举报
回复
你程序是一节一节发的,结果当然是那样了

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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