socket异步传输,发送和接收缓冲区都设为1024,在局域网内传文件峰值只能到800K/s,而且传输一个5M的文件接收端都程序最后会占到100多M内存,发送端(手机)就更别提了,本来就只有40多M RAM了,发送超过10M的文件一定会报OutOfMemory。我大概知道问题在哪,但确实不知道如何解决。发送和接收的代码如下,请大大们有空时指点下。
/// 发送数据
public void Send(Socket handler, byte[] data)
{
StateObject obj = new StateObject();
obj.workSocket = handler;
obj.senddatalength = 0; //用来记录已发送多少数据,主要是为了知道发送进度。
obj.senddata = data ; //这句肯定是占内存的大头,可是如果不把要发送的数据储存在这,发送回调里怎么知道接下来应该发送哪一段数据呢?
int len = bufferlength;
if (obj.senddata.Length< StateObject.BufferSize)
{
len = obj.senddata.Length;
}
handler.BeginSend(obj.senddata, 0, len, 0,
new AsyncCallback(SendCallback), obj);
} /// 发送回调
private void SendCallback(IAsyncResult ar)
{
StateObject obj = (StateObject)ar.AsyncState;
int bytesSent = obj.workSocket.EndSend(ar);
obj.senddatalength = obj.senddatalength + bytesSent;
if (bytesSent == 0)
{
if (sendcompleted != null)
{
sendcompleted();
}
obj.workSocket.Shutdown(SocketShutdown.Both);
obj.workSocket.Close();
}
else
{
if (sddata != null)
{
sddata(obj.senddatalength);
}
int sendlength = bufferlength;
if (obj.senddatalength + bufferlength > obj.senddata.Length)
{
sendlength = obj.senddata.Length - obj.senddatalength;
}
obj.workSocket.BeginSend(obj.senddata, obj.senddatalength, sendlength, 0,
new AsyncCallback(SendCallback), obj); //通过senddatalength来确定这次发送哪段数据
}
}
///接收回调
public void readCallback(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead;
try
{
bytesRead = handler.EndReceive(ar);
}
catch (Exception)
{
return;
}
if (bytesRead > 0)
{
byte[] tempbt = new byte[bytesRead];
Array.Copy(state.buffer, 0, tempbt, 0, bytesRead);
state.data.AddRange(tempbt); //state.data是arraylist 用来储存已经接收到的数据
if (rcdata != null)
{
rcdata(state.data.Count); //事件 报告已接收多少数据
}
state.buffer = new Byte[bytesRead];
state.workSocket.BeginReceive(state.buffer, 0, bytesRead, 0,
new AsyncCallback(readCallback), state); }
else
{
state.workSocket.Shutdown(SocketShutdown.Both);
state.workSocket.Close();
if (receivecompleted!=null)
{
receivecompleted(state);
}
}
}
/// 发送数据
public void Send(Socket handler, byte[] data)
{
StateObject obj = new StateObject();
obj.workSocket = handler;
obj.senddatalength = 0; //用来记录已发送多少数据,主要是为了知道发送进度。
obj.senddata = data ; //这句肯定是占内存的大头,可是如果不把要发送的数据储存在这,发送回调里怎么知道接下来应该发送哪一段数据呢?
int len = bufferlength;
if (obj.senddata.Length< StateObject.BufferSize)
{
len = obj.senddata.Length;
}
handler.BeginSend(obj.senddata, 0, len, 0,
new AsyncCallback(SendCallback), obj);
} /// 发送回调
private void SendCallback(IAsyncResult ar)
{
StateObject obj = (StateObject)ar.AsyncState;
int bytesSent = obj.workSocket.EndSend(ar);
obj.senddatalength = obj.senddatalength + bytesSent;
if (bytesSent == 0)
{
if (sendcompleted != null)
{
sendcompleted();
}
obj.workSocket.Shutdown(SocketShutdown.Both);
obj.workSocket.Close();
}
else
{
if (sddata != null)
{
sddata(obj.senddatalength);
}
int sendlength = bufferlength;
if (obj.senddatalength + bufferlength > obj.senddata.Length)
{
sendlength = obj.senddata.Length - obj.senddatalength;
}
obj.workSocket.BeginSend(obj.senddata, obj.senddatalength, sendlength, 0,
new AsyncCallback(SendCallback), obj); //通过senddatalength来确定这次发送哪段数据
}
}
///接收回调
public void readCallback(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead;
try
{
bytesRead = handler.EndReceive(ar);
}
catch (Exception)
{
return;
}
if (bytesRead > 0)
{
byte[] tempbt = new byte[bytesRead];
Array.Copy(state.buffer, 0, tempbt, 0, bytesRead);
state.data.AddRange(tempbt); //state.data是arraylist 用来储存已经接收到的数据
if (rcdata != null)
{
rcdata(state.data.Count); //事件 报告已接收多少数据
}
state.buffer = new Byte[bytesRead];
state.workSocket.BeginReceive(state.buffer, 0, bytesRead, 0,
new AsyncCallback(readCallback), state); }
else
{
state.workSocket.Shutdown(SocketShutdown.Both);
state.workSocket.Close();
if (receivecompleted!=null)
{
receivecompleted(state);
}
}
}
解决方案 »
- 字符串如何进行换位
- 未将对象引用设置到对象的实例。
- 初学:程序的速度和负载问题
- 如何调用外部文件在线等待.
- 如何在状态栏statusBar1里面画个方块之类的图型
- 思归,秋风高手们说说....(好像我的问题每次都不得而终,比较郁闷...(主要问题和分数在另一页面,))
- system.runtime.remoting.channels.tcp出错,高手快来看看!!!
- 求简单winform资料开发资料c#的,就是简单的各个控件的运用介绍,我做webform的,对winform不熟悉;谢谢!!
- 我的.net程序调用一个com+组件,组件对两个服务器的数据库操作,可是提示0x8004d00e。如果对一个服务操作就没问题
- API引用??
- 求:C# 出题系统 B/S架构 生成带密封线的WORD试卷 C# 出题系统 B/S架构 生成带密封线的WORD试卷
- C# 中加入一个3D场景,然后再加入一个汽车模型,怎样能随意调转汽车的方向(转向)
是啊,我也在想,不知道大家在做socket传输时,是先把文件拆了再发,还是先读进内存再分批发送呢。。
文件分块的代码用C#来写,这样速度会快很多很多;