关于socket传输速度的问题!

一只熊猫 2010-05-18 11:26:12
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);
}
}
}
...全文
2238 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
nzzb1985 2010-06-17
  • 打赏
  • 举报
回复
学习下
ztenv 2010-05-19
  • 打赏
  • 举报
回复
就是像C#调用C++函数一样,你的C++库最好导出函数(建立/关闭连接,收/发数据),因为C#没有办法用C++的类,
hongqun369 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lianshaohua 的回复:]
C#的socket真的效率很低,建议传输部分写成C++的,然后用C#来调用;
文件分块的代码用C#来写,这样速度会快很多很多;
[/Quote]
传输部分写成C++的,然后用C#来调用;
怎么调用?
一只熊猫 2010-05-19
  • 打赏
  • 举报
回复
哎 C#效率是比较低,可是不会C++啊,临时学就算做出来了我估计也是不稳定的。

我再多做做测试吧,看到底能不能到达能接受的速度。
ztenv 2010-05-18
  • 打赏
  • 举报
回复
C#的socket真的效率很低,建议传输部分写成C++的,然后用C#来调用;
文件分块的代码用C#来写,这样速度会快很多很多;
一只熊猫 2010-05-18
  • 打赏
  • 举报
回复
http://www.csharpwin.com/csharpresource/1135.shtml

这里有篇socket的文章,原码相当的不错,有md5验证、接收者可选择接收或拒绝等等,但用的是udp。

可惜手机上没有udp类,不然.... 呵呵
ztenv 2010-05-18
  • 打赏
  • 举报
回复
做文件传输时,一定要先分块,再传输,如果不会块就会死得很惨很惨的;
jerry_k 2010-05-18
  • 打赏
  • 举报
回复
MARK 帮顶。。我也遇到了这样的问题。
一只熊猫 2010-05-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yuanhuiqiao 的回复:]

拆分成几部分发?
[/Quote]

是啊,我也在想,不知道大家在做socket传输时,是先把文件拆了再发,还是先读进内存再分批发送呢。。
yuanhuiqiao 2010-05-18
  • 打赏
  • 举报
回复
拆分成几部分发?
deknight 2010-05-18
  • 打赏
  • 举报
回复
帮顶 mark
happyboyxq1985 2010-05-18
  • 打赏
  • 举报
回复
MARK 帮顶

110,552

社区成员

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

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

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