读书人

Socket 异步接收 缓冲区产生改变

发布时间: 2013-11-27 21:59:41 作者: rapoo

Socket 异步接收 缓冲区发生改变
采用异步发送和接收的方式。
发送代码


public void ASend(string Name,byte[] Content,int size)
{
if (mSocket == null)
throw new ArgumentNullException("连接不存在");
if (Content == null)
return;
MyTreaty my = new MyTreaty(Name, Content,size);
byte[] SendData = my.GetBytes();
try
{
//先得到数据包的长度
int len = SendData.Length;
//把数据包的长度写入byte数组中
byte[] head = BitConverter.GetBytes(len);
byte[] newByte = new byte[head.Length + len];
Array.Copy(head, 0, newByte, 0, head.Length);
Array.Copy(SendData, 0, newByte, 4, len);
mSocket.BeginSend(newByte, 0, newByte.Length, 0, new AsyncCallback(SendCallBack), mSocket);
}
catch(Exception ex)
{
}
}

接收代码
        private void ReceiveCallback(IAsyncResult ar)
{
try
{
//
StateObject state = ar.AsyncState as StateObject;
//读取数据
int bytesRead = mSocket.EndReceive(ar);
if (bytesRead > 0)
{
byte[] head = new byte[4];
Array.Copy(state.buffer, 0, head, 0, 4);
//计算包头的长度
int length = BitConverter.ToInt32(head, 0);
byte[] data = new byte[length];
Array.Copy(state.buffer, 4, data, 0, length);
MyTreaty my = MyTreaty.GetMyTreaty(data);
if (onStreamData != null)
onStreamData(my);
Thread.Sleep(10);
mSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);

}
}
catch (SocketException se)
{
if (onClosed != null)


onClosed(ID, se.Message);
}
catch (Exception e)
{
throw new ApplicationException(e.Message);
}
}



主要实现为了本地不断的截屏(1秒钟20次左右),然后通过Socket发送到远程服务器并在服务器显示这么一个功能(局域网)。

本地测试1秒钟发送20次 每次字节数在8W左右 服务器接收端3分钟左右崩溃
如果是局域网测试,也是1秒钟发送20次的话,只能接收到第一次的数据,然后缓冲区错误崩溃。

求高人指点。
如有源码更好。
谢谢. Socket C# .NET 异步
[解决办法]
你难道只是内网使用?你这速度要求带宽至少要20M,而且不能有其它网络流量占用。
从你的代码上看,很可能是来不及接收数据了,本来就必须要求很快的数据接收,你还中间休息下(20毫秒),网卡的缓冲区早溢出了。
[解决办法]
引用:
Quote: 引用:

你难道只是内网使用?你这速度要求带宽至少要20M,而且不能有其它网络流量占用。
从你的代码上看,很可能是来不及接收数据了,本来就必须要求很快的数据接收,你还中间休息下(20毫秒),网卡的缓冲区早溢出了。

对的,目前只考虑局域网,但是是通过无线网络。
那个sleep 是我后面加上去的,没有也是一样出错的。
那有什么比较好的方案吧?是不是只有采用阻塞的方式了?

因为要传的东西太多了。
[解决办法]
你默认收到包长度先,实际上可能是上一包的中间部分,这样长度就错了。

加个包头的吧,先验证包头的特殊字符,然后才是包长。
[解决办法]
引用:
按你现在的接收逻辑,
int bytesRead = mSocket.EndReceive(ar);

此时整个包必须收全才能正确的收下一个包,
因为你默认下一次收到的是下一个包头。

若是包不全,下一次收到的是包第二部份, 你的程序就错了。
+1
[解决办法]
可以自定义一个协议 规定一个 Head 跟 Food (不对英文的正确性负责)
然后一条一条的放到队列里。一条处理完 再处理下一条!
[解决办法]
socket的同步阻塞式和异步,只是编程方法不同,传输效率是一样的

1秒钟发送20次 每次字节数在8W,
80K*20 = 1600K = 1.6MBps = 16Mbps

100M以上的网络就应该没问题的
[解决办法]
引用:
Quote: 引用:

可以自定义一个协议 规定一个 Head 跟 Food (不对英文的正确性负责)
然后一条一条的放到队列里。一条处理完 再处理下一条!

如果我用阻塞式发送,发完一张再接着发下一张,局域网socket传输效率能满足我投影桌面的要求吗?

与发送方式无关!

读书人网 >C#

热点推荐