异步回调发送变长消息

happymanlxj 2007-09-27 03:31:48
socket编写c/s结构程序中,异步回调怎样发送和接收变长消息!
...全文
221 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
ezhuyin 2007-09-28
  • 打赏
  • 举报
回复
消息最长可发多长?上面的代码能保证同时从一个客户机上接收多条消息而不产生混乱吗?

消息的长度随意。因为采用的是TCP/IP协议,所以一个Socket对应一台客户机,所以,为每一台客户机都建立一个新的ReceiveBuffer。
============================================================

b.count = b.EndReceive(ar);接收的长度能比b.buff.Length大吗?

b.count的长度不可能超过b.buff.Length。所以,每次到了最后,都判断是否还有数据需要接收,如果有,则重新开始异步调用,继续接收数据。

if (b.sock.Available>0)
Receive(b);
}
==================================================

如果要加长度,就这样
public byte[] AddHeader(byte[] data)
{
uint length = (uint)data.Length;
byte[] datatosend = new byte[4+length]; // 指定长度为32位的信息长

// 将数据挪入
datatosend[0] = (byte)(length & 0xff);
datatosend[1] = (byte)(length >> 8 & 0xff);
datatosend[2] = (byte)(length >> 16 & 0xff);
datatosend[3] = (byte)(length >> 24 & 0xff);

// 重建发送数据
data.CopyTo(datatosend, 4, length);

return datatosend;
}

接收数据的时候,先接受4位,判断长度,再接收剩余数据。
注意:这里讨论的只是“消息”的发送。消息长度超过64k的话,就要分片传输。
这里只是给一个大概的代码,没调试过。
happymanlxj 2007-09-28
  • 打赏
  • 举报
回复
我想在消息前面加上长度信息,但接收的时候不知怎么处理?
happymanlxj 2007-09-28
  • 打赏
  • 举报
回复
消息最长可发多长?上面的代码能保证同时从一个客户机上接收多条消息而不产生混乱吗?

b.count = b.EndReceive(ar);接收的长度能比b.buff.Length大吗?
ezhuyin 2007-09-28
  • 打赏
  • 举报
回复
那倒不会。接收完毕以后回调自动结束。这时候把客户机消息加到一个队列中进行处理,然后清空ReceiveBuffer,接收下一条消息。
happymanlxj 2007-09-28
  • 打赏
  • 举报
回复
所以一个Socket对应一台客户机,所以,为每一台客户机都建立一个新的ReceiveBuffer。

.................................................................................

如果同一台客户机连续发送多条消息也会引起混乱!
ezhuyin 2007-09-27
  • 打赏
  • 举报
回复
如果消息不很长的话,发送可以一次全部发送完

{
Socket s;
byte[] buff;
.... // 省略部分
s.BeginSend(buff, 0, buff.Length, SocketFlags.None,
new AsyncCallback(EndSendCallback), s);
// 异步发送结束,可以去做别的事情了
}

... 下面的异步发送的回调
private void EndSendCallback(IAsyncResult ar)
{
Socket s = (Socket)ar.AsyncState;
s.EndSend(ar);
}

接收比较麻烦点,因为不知道要接收多少,我们可以分段接收,然后重组
public struct ReceiveBuffer
{
Socket sock;
pubic Queue<byte[]> data;
public byte[] buff;
public int count;
public int totallength;
}

public void Receive(ReceiveBuffer b)
{
// 准备接收数据
b.buff = new byte[1024];
b.count = 0;
if (b.data.Count==0)
b.totallength = 0;
// 开始接收
b.sock.BeginReceive(b.buff, 0, b.buff.Length, SocketFlags.None,
new AsyncCallback(EndReceiveCallback), b)
}

private void EndReceiveCallback(IAsyncResult ar)
{
ReceiveBuffer b = (ReceiveBuffer)ar.AsyncState;
b.count = b.EndReceive(ar);
if (b.Length>b.count)
{
byte[] shallow = new byte[b.count];
for(int i=0; i<b.count; i++)
{
shallow[i]=b.buff[i];
}
b.data.Enqueue(shallow);
}
else
{
b.data.Enqueue(b.buff);
}
b.totallength += b.count;
if (b.sock.Available>0)
Receive(b);
}

全部数据都会放在ReceiveBuffer.data里面,最后按照顺序取出来就可以了。
happymanlxj 2007-09-27
  • 打赏
  • 举报
回复
就是长度不定,有长消息有短的消息!
ezhuyin 2007-09-27
  • 打赏
  • 举报
回复
弱弱问一下:什么叫“变长”?

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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