CAsyncSocket TCP协议通信速度慢的问题请教

MilitaryMiniatures 2005-05-09 12:43:39
两台公众网上的机器用PCAnywhere连接起来后,用PCAnywhere传输文件,速度能达到约50K Byte/s的速度传输文件,一个700K的文件,也就是几秒钟能够传输完成。

自己用MFC写程序连接,采用tcp/ip协议建立连接,使用了CAsyncSocket建立连接, SOCK_STREAM类型。发送方,不停地发送数据,或者在CAsyncSocket::OnSend中发送数据,接受方在OnReceive中接受数据,速度爆满,顶多有几百字节/秒的传输速度。
如果发送方的报文,也就是每一次CAsyncSocket::Send的报文大小,设置为1K以上,那么,很可能就堵塞了:很长时间过不来,然后突然间可能过来了。
如果发送方的报文,也就是每一次CAsyncSocket::Send的报文大小,设置为256或者更小,则报文能断断续续过来,可是仍然爆慢。
另外发送方的发送缓冲区,如果设置为很大,则大多数报文反而被堵塞。
自己写程序实现通信,传输700k的文件,起码需要半个多小时。相比PcAnywhere的传输速度,一个天上一个地下,可是,不知道为什么?

请问,可能原因是什么,如何解决?
谢谢!
...全文
386 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
KelvinSpace 2005-05-11
  • 打赏
  • 举报
回复
哈哈~网的信息也许太多
我当时也是找了很久才找到
网上传送时,要控制的不[发送端]而是[接收端]
//接受端
void CDataSocket::OnReceive(int nErrorCode)
{
if (nErrorCode == 0)
{
char buf[1024];
int nTotal = TOTAL //实际文件大小
while (nTotal) // loop until break
{
int n = Receive(buf, nTotal);
if ((n == 0) || (n == -1))
{
break;
}
nTotal -= n;
}
}
}

//发送端
如果有足够的空间,一次发100M也可以
如果没有,也可以分段读入文件
void CDataSocket::SendData(int len, char* buf)
{
int n = 0;
int m = CAsyncSocket::Send(buf , len);
if (m == -1)
{
if (CAsyncSocket::GetLastError() != WSAEWOULDBLOCK)
{ // error
break;
}
}
}

流程
发送端:
1)发送一个结构(含文件大小)
2)发送文件
接收端
1)接收自义结构
2)根据文件大小,接收文件
我的例程
http://www.vckbase.com/code/listcode.asp?mclsid=9&sclsid=919


Superliyingxin 2005-05-10
  • 打赏
  • 举报
回复
我听说,传输大的文件要用winsock套接字比较好,用MFC套接字如CSocket或CAsyncSocket可能会传输错误或数据不正确。这是我听说的。仅供参考!!!!~
VCSQLVB 2005-05-09
  • 打赏
  • 举报
回复
PCAnywhere很可能采用了多线程,将大文件分成N份用N个线程同时发送。
我在做HTTP下载时,只要服务器没限制连接数,用10个线程同时下比flashGet快多了。
MilitaryMiniatures 2005-05-09
  • 打赏
  • 举报
回复
谢谢大家关心!

事实上,我也正在希望我的程序有问题,主要是我实在不知道问题在那里。

测试程序很简单,server端,一个CAsyncSocket的派生类对象,实现侦听功能,侦听成功后,Accept一个CDataSocket对象。Client端,一个CDataSocket对象,直接Connect Server端的Listen地址和端口。然后不对CDataSocket对象做处理,Server端开始向其发送数据。不停地发,直到发不出去(或者文件结束),如果发不出去,则等待。Client端,则在OnReceive中Receive数据。仅此而已。
现在可以说说今天努力的结果了:

1,如果不对socket做任何处理,如果Server端发送的数据报文每次大小(也就是CAsyncSocket::Send的大小)为256字节以下,则已开始能传输,后来就很容易堵塞,然后堵塞很长时间,突然间,能过来一段数据;这个显然不是我想要的结果。如果Server端发送的数据报文每次都比较大,比如>1024,则很容易堵塞。

2,后来对Socket作了处理,第一个处理是限制发送缓冲区的大小,这样,我只要发送几个数据报文,发送缓冲区就满了,后面的数据只有等待了。我用了CAsyncSocket::SetSockOpt——好像是这个函数——把发送缓冲区限制为256/512字节,效果已经渐渐明显起来,已经基本上不堵塞了,不过,传输速度依然很慢;只是基本上不堵塞了。报文大小设定为128字节,效果最好;

3,为了再次提高速度,又设定了两个参数,如下(都是CAsyncSocket::SetSockOpt实现的):
(1)TCP_NODELAY=TRUE
(2)SO_DONTROUTE
这么设定之后,速度大大提高,传输700K,最快的速度,我调试出来是2分钟左右。可是距离PcAnywhere传输的速度依然慢很多(它这个基本上30-40秒能搞定)不过,对我现在来说,已经是一个很大的进步了!每个报文设定为128字节,则总传输时间约在2分钟左右,如果设定为68字节,则总传输时间约在4分半左右。

en.现象就是这样,代码很简单,可惜,在公司,否则我就copy上来了。
凭我的记忆,写上一点关键代码:

//接受端
void CDataSocket::OnReceive(int nErrorCode)
{
if (nErrorCode == 0)
{
char buf[1024];
while (true) // loop until break
{
int n = Receive(buf, 1024);
if ((n == 0) || (n == -1))
{
break;
}
}
}
}

//发送端
#define PACKET_SIZE 128
void CDataSocket::SendData(int len, char* buf)
{
int n = 0;
while (n < len)
{
int m = CAsyncSocket::Send(buf + n, min(PACKET_SIZE, len - n));
if (m > 0) n += m;
else if (m == -1)
{
if (CAsyncSocket::GetLastError() != WSAEWOULDBLOCK)
{ // error
break;
}
}
}
}
Phourm 2005-05-09
  • 打赏
  • 举报
回复
自己写程序实现通信,传输700k的文件,起码需要半个多小时。
你的程序一定有问题!在局域网上先试一下!排除网络的问题!
9731boy 2005-05-09
  • 打赏
  • 举报
回复
一般不推荐用MFC::CSocket的吧
我宁愿自己写一个

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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