用Socket连继发送信息,造成数据丢失怎么办?

lbllbl 2003-11-11 04:07:41
我是用BCB5自带的TClientSocket与TServerSocket写的程序:
客户登录服务器时,我就把产生的相应Socket保存到一个数组CliSck[]中,之后我把某个客户端发来的信息转发给其它客户端。写了两段转发信息的代码如下:
注1:其中 sckServer 是 TServerSocket对象
注2:我是在一台机上做的调试
《代码1》
for(i=0;i<sckServer->Socket->ActiveConnections;i++)
{
sckServer->Socket->Connections[i]->SendBuf(Buf,32);
}
《代码2》
CliSck[0]->SendBuf(Buf,32);
CliSck[1]->SendBuf(Buf,32);
CliSck[2]->SendBuf(Buf,32);
CliSck[3]->SendBuf(Buf,32);

问题:
执行第1段没有出现过错误,Buf里的信息被成功的发送到每个客户端。
但执行第2段常出现各种错误,有时正常,有时Buf里的信息只被发送到一个客户端,其它三个客户端什么也没收到。

后来我把第2段代码改为如下:
《代码3》
CliSck[0]->SendBuf(Buf,32); Sleep(100);
CliSck[1]->SendBuf(Buf,32); Sleep(100);
CliSck[2]->SendBuf(Buf,32); Sleep(100);
CliSck[3]->SendBuf(Buf,32);

这样一改后结果正常了,但这是为什么?

望高手指教!



...全文
325 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
lbllbl 2003-11-16
  • 打赏
  • 举报
回复
有人能解释一下我这个问题吗?
耙子 2003-11-12
  • 打赏
  • 举报
回复
类似你这类的程序,ServerSocket最好采用阻塞式线程,效果要好得多。这样就不会应为某个连接网络不好而影响其他连接的问题。

从D7开始,已经默认不安装TServerSocket这些控件,而是建议使用Indy控件了。
lbllbl 2003-11-12
  • 打赏
  • 举报
回复

... ...
客户登录服务器时,我就把产生的相应Socket保存到一个数组CliSck[]中,
... ...

定义如下:
TCustomWinSocket *CliSck[100];
与 ServerSocket->Socket->Connections 是同一类东西。
yesry 2003-11-11
  • 打赏
  • 举报
回复
搂住代码贴得不全啊。

sckServer->Socket->Connections[0]->SendBuf(Buf,32);
sckServer->Socket->Connections[1]->SendBuf(Buf,32);
sckServer->Socket->Connections[2]->SendBuf(Buf,32);
sckServer->Socket->Connections[3]->SendBuf(Buf,32);

不知道数组CliSck是什么。
wyb_45 2003-11-11
  • 打赏
  • 举报
回复
即然是自己组包,那么我有如下建议
自己定义数据包的格式
定义传输包的包头包体等信息,自己组包发送和接收
而且加入校验功能,
我以前做过传输文件的程序,就是这种思路,很安全可靠。
是采取一应一答的方式
客户发送请求包(1)包标识为1
服务端发送包包标识为1
客户收到包后,发第二个请求包
。。。
直到结束
wyb45@sohu.com
xizhouhawk 2003-11-11
  • 打赏
  • 举报
回复
没道理啊,会不会是:
CliSck[1]->SendBuf(Buf,32);在CliSck[0]->SendBuf(Buf,32);
还没来得及将数据完全发出去之前就将数据缓冲重写了,造成了数据丢失!
这情况想来也不对啊,每个Socket对应不同的Port,按道理不会现现这种情况啊?
你用的是TCP socket还是UDP socket,如果是后者的话,这种情况还是有可能, 这就你自己控制重发了.
Atomictry 2003-11-11
  • 打赏
  • 举报
回复
建议用第一种方式全发,第二种方法一定要加sleep();
叶子哟 2003-11-11
  • 打赏
  • 举报
回复
CliSck中什么东东?你如何产生的?
Atomictry 2003-11-11
  • 打赏
  • 举报
回复
我用bcb6.0的例子用你的第二种方法,不加sleep()都是可以实现向各个客户端全发的。
但是不是用你CliSck[0]->SendBuf(Buf,32);来做的。

我用的是ServerSocket->Socket->Connections[0]->SendBuf(Buf,32);
ServerSocket->Socket->Connections[1]->SendBuf(Buf,32);
ServerSocket->Socket->Connections[2]->SendBuf(Buf,32);这种方法。
A
控件的name

不明白你的CliSck[i]->SendBuf(Buf,32)中的CliSck[i]从哪来的。
lbllbl 2003-11-11
  • 打赏
  • 举报
回复
“ Atomictry(天影)
建议用第一种方式全发,第二种方法一定要加sleep();”

为什么用第1种方法行,第二种方法就不行,不都是一次向多个客户端发送信息吗。


1,317

社区成员

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

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