Socket发送数据重叠问题!!!

musics52 2008-11-24 12:22:51
第一次在CSDN发帖子,请多多帮忙~~~小弟不胜感激。。。。
我要做的一件事情是一个Socket服务器,多个Socket客户端。服务器负责客户端之间的数据转发。。。。
很简单吧?
可是我还是遇到问题了。。。一直没有找到答案。
数据传输中遇到这样的问题:发送给客户端A的数据还没有发送出去,又有新的发送给A的数据要发送了。于是两个本来应该独立发送的数据被一起发送给A。
客户端A收到这个数据的时候,(XML格式的),由于有两条数据,两个XML数据,客户端就不认了,无法解析回一个XML文档。。。。
怎么办?
客户端Socket是使用Flash中的XMLSocket,服务器端使用C++中的CAsyncSocket。客户端进行修改的可能性比价小,因为只要不是XML格式的,它都收不到,我在想有没有办法让服务器端在发送完一次数据之后再发送新的数据呢?而不要把多个数据合在一起发送。接收数据的时候可能也存在问题。如果一条数据还没有读取完的时候又有新的数据进来,这个时候如何避免两条数据相互干扰?
小弟对Socket机制了解甚少,不得其门而入,轻诸位帮帮忙。。。。
...全文
491 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
cowcs 2008-11-26
  • 打赏
  • 举报
回复
恭喜了。不好意思,没能帮上什么忙。看来还是要靠自己看的,呵呵。
musics52 2008-11-26
  • 打赏
  • 举报
回复
搞定了!!!我简单地在没条信息的最后加上一个\0字节,然后收到数据的时候以它为分割点进行分割就可以了。因为我传输的是字符串,所以用\0不会有歧义。谢谢cowcs也谢谢jenneyvanus。。。。
cowcs 2008-11-25
  • 打赏
  • 举报
回复
楼上有牛人出现,先膜拜下。
异步方面应该可以改进的。
cowcs 2008-11-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 musics52 的回复:]
你这样的代码肯定有问题!
我觉得你没有考虑到异步操作的问题。
Send函数在调用后会立即返回的。所以不存在Send函数还没有执行完毕的问题。while循环就没有意义了。(如果返回错误,将变成死循环)。
我原先怀疑的是,执行Send函数之后,系统会创建一个新的线程来发送数据,也就是Send函数返回的时候,缓冲区的数据还没有发送出去。此时又有新的数据要Send了,就合并在原有的缓冲区中一起发送。
可是我用CArchive类的flus…
[/Quote]
异步上可能会有点问题。另外,由于你说发送会延时,也就是并不立即调用send()函数,所以我就假设send()函数需要执行时间(也就是while()里面的send()并不立即执行完毕),具体的延时发送是如何造成的,我是不知道的。如果立即就发送了的话,那你说的问题就不存在了,是不是?
用户 昵称 2008-11-25
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 musics52 的回复:]
我是从实际接收到的数据发现的,两次Send的数据被一次性发送到客户端了。我要解决的也就是这个问题。
我认为是开了一个新的线程来发送数据,也就是说就算Send函数有返回值,也不确定数据已经发送出去,所以直接取Send函数的返回值是没有意义的。
不知道是不是这样的。
[/Quote]

客户端自己折包。
用户 昵称 2008-11-25
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 musics52 的回复:]
我是从实际接收到的数据发现的,两次Send的数据被一次性发送到客户端了。我要解决的也就是这个问题。
我认为是开了一个新的线程来发送数据,也就是说就算Send函数有返回值,也不确定数据已经发送出去,所以直接取Send函数的返回值是没有意义的。
不知道是不是这样的。
[/Quote]

客户端自己折包。
cowcs 2008-11-24
  • 打赏
  • 举报
回复
个人的愚见,那你就在服务器端加锁,我打个比方,最简单的是定义一个变量,bool send;
初始为false,一开始服务器端没有要发送的数据,一会第一个要发送的数据来了,这时将send置为TRUE。等待进行发送,如果又有新的数据要发送了,这时一看send标志为true,则不把他和刚刚的数据放的一起,直到第一数据被发送给了客户端了,才将send置为FALSE,后面的数据再操作。

别鄙视我。
musics52 2008-11-24
  • 打赏
  • 举报
回复
Socket就是套接字吧?
加锁操作怎么做呢?
我的问题是在发送端,发送端将两条信息一起发送了,如何保证发送完一条信息之后再发送新的信息?
似乎是使用CArchive的flush方法来实现,不知可否?CAsyncSocket如何使用CArchive对象呢?
musics52 2008-11-24
  • 打赏
  • 举报
回复
我现在可以确认的是,不管是服务器端还是客户端,只要发送或者接收的多段数据的间隔非常短,就会被自动合并接收,然后才触发onRecieve事件。想在Socket层次解决每条消息分离的目标看来是不可能实现的了。
我想可能要对消息的格式进行新的定义,以便能够识别出多条合并在一起的消息,才能解决我遇到的问题。
musics52 2008-11-24
  • 打赏
  • 举报
回复
你这样的代码肯定有问题!
我觉得你没有考虑到异步操作的问题。
Send函数在调用后会立即返回的。所以不存在Send函数还没有执行完毕的问题。while循环就没有意义了。(如果返回错误,将变成死循环)。
我原先怀疑的是,执行Send函数之后,系统会创建一个新的线程来发送数据,也就是Send函数返回的时候,缓冲区的数据还没有发送出去。此时又有新的数据要Send了,就合并在原有的缓冲区中一起发送。
可是我用CArchive类的flush方法强行将缓冲区的数据发送完毕后再返回,问题还是没有解决。实在太奇怪了。
于是我想可能是接收端出问题了,两条几乎同时到达的消息被合并成一条消息了。
这可怎么办啊?到底有没有将每一条消息都清楚地分开的方法啊?
cowcs 2008-11-24
  • 打赏
  • 举报
回复
可以用套接字吧,操作系统里不是有介绍互斥对象吗?相当于加了把锁,也就是客户端收到数据后就加上锁,这时服务器端数据再发过来时,先判断,一看锁住了,就不能接收了。等到客户端处理完了再解锁,又可以接受下一条数据了。不知道可不可以?
musics52 2008-11-24
  • 打赏
  • 举报
回复
没人回答,自己顶一个先``
cowcs 2008-11-24
  • 打赏
  • 举报
回复
bool Issend;
Issend = true;
Judge = false;
int Cansend;
每次要发送数据时就执行下面的while()
while(!Judge)
{
if(Issend)
{
Issend = false;
Cansend = send();
if(Cansend != Erro)
{
Issend = true;
Judge = true;//or break;
}//if(Cansend != Erro)

}//if(Issend)
}
比如第一次的数据来了,执行while(),里面的send()函数还没执行完毕,这时又来了一个发送数据的。再执行while(),这时由于Issend的值是false,所以send()就不能被调用。不过这样肯定还会有问题,可应该起码解决了你说的了吧。
musics52 2008-11-24
  • 打赏
  • 举报
回复
我说的瞎循环是土话,呵呵。
bool send;
send=true;
if(Send(信息)没错){
send=false;
}



//有新的数据要传输
while(!send){
//空
}
Send(新信息);

你的意思是这个吗?

太奇怪了吧~!
musics52 2008-11-24
  • 打赏
  • 举报
回复
我是从实际接收到的数据发现的,两次Send的数据被一次性发送到客户端了。我要解决的也就是这个问题。
我认为是开了一个新的线程来发送数据,也就是说就算Send函数有返回值,也不确定数据已经发送出去,所以直接取Send函数的返回值是没有意义的。
不知道是不是这样的。
cowcs 2008-11-24
  • 打赏
  • 举报
回复
搞不明白,你的send 为什么要稍候发送,等数据吗?可又不是。
什么叫瞎循环?
那就把锁加在在send()函数外,send函数不是有返回值吗?发送成功了就解锁。

再加个控制变量不就行了。没有加锁,进入临界区了,执行了send函数了,就改变变量的值,就可以退出循环,否则继续循环,(要不就等待一下再循环)。
musics52 2008-11-24
  • 打赏
  • 举报
回复
怎么知道第一数据被发送给了客户端了?
有触发什么事件吗?
musics52 2008-11-24
  • 打赏
  • 举报
回复
问题是怎么控制数据的发送呢?什么时候发送完毕?sokcet在调用Send函数的时候,并没有直接发送数据,而是在稍后再发送。(多线程?)这时如果再调用新的Send的时候,两次的数据就被合在一起发送了。如果用你说的方法,什么时候将send再次置为false?如果send为true,有新的数据要发送的时候如何实现“等send是false的时候再发送”?用while循环吗?那岂不是程序瞎循环?
好像是很简单的问题,怎么我就是搞不定!!哎

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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