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毫秒),网卡的缓冲区早溢出了。
[解决办法]
因为要传的东西太多了。
[解决办法]
你默认收到包长度先,实际上可能是上一包的中间部分,这样长度就错了。
加个包头的吧,先验证包头的特殊字符,然后才是包长。
[解决办法]
按你现在的接收逻辑,
int bytesRead = mSocket.EndReceive(ar);
此时整个包必须收全才能正确的收下一个包,
因为你默认下一次收到的是下一个包头。
若是包不全,下一次收到的是包第二部份, 你的程序就错了。
[解决办法]
可以自定义一个协议 规定一个 Head 跟 Food (不对英文的正确性负责)
然后一条一条的放到队列里。一条处理完 再处理下一条!
[解决办法]
socket的同步阻塞式和异步,只是编程方法不同,传输效率是一样的
1秒钟发送20次 每次字节数在8W,
80K*20 = 1600K = 1.6MBps = 16Mbps
100M以上的网络就应该没问题的
[解决办法]
可以自定义一个协议 规定一个 Head 跟 Food (不对英文的正确性负责)
然后一条一条的放到队列里。一条处理完 再处理下一条!
如果我用阻塞式发送,发完一张再接着发下一张,局域网socket传输效率能满足我投影桌面的要求吗?
与发送方式无关!