两台公众网上的机器用PCAnywhere连接起来后,用PCAnywhere传输文件,速度能达到约50K Byte/s的速度传输文件,一个700K的文件,也就是几秒钟能够传输完成。自己用MFC写程序连接,采用tcp/ip协议建立连接,使用了CAsyncSocket建立连接, SOCK_STREAM类型。发送方,不停地发送数据,或者在CAsyncSocket::OnSend中发送数据,接受方在OnReceive中接受数据,速度爆满,顶多有几百字节/秒的传输速度。
如果发送方的报文,也就是每一次CAsyncSocket::Send的报文大小,设置为1K以上,那么,很可能就堵塞了:很长时间过不来,然后突然间可能过来了。
如果发送方的报文,也就是每一次CAsyncSocket::Send的报文大小,设置为256或者更小,则报文能断断续续过来,可是仍然爆慢。
另外发送方的发送缓冲区,如果设置为很大,则大多数报文反而被堵塞。
自己写程序实现通信,传输700k的文件,起码需要半个多小时。相比PcAnywhere的传输速度,一个天上一个地下,可是,不知道为什么?请问,可能原因是什么,如何解决?
谢谢!
如果发送方的报文,也就是每一次CAsyncSocket::Send的报文大小,设置为1K以上,那么,很可能就堵塞了:很长时间过不来,然后突然间可能过来了。
如果发送方的报文,也就是每一次CAsyncSocket::Send的报文大小,设置为256或者更小,则报文能断断续续过来,可是仍然爆慢。
另外发送方的发送缓冲区,如果设置为很大,则大多数报文反而被堵塞。
自己写程序实现通信,传输700k的文件,起码需要半个多小时。相比PcAnywhere的传输速度,一个天上一个地下,可是,不知道为什么?请问,可能原因是什么,如何解决?
谢谢!
我在做HTTP下载时,只要服务器没限制连接数,用10个线程同时下比flashGet快多了。
我宁愿自己写一个
现在可以说说今天努力的结果了: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;
}
}
}
}
我当时也是找了很久才找到
网上传送时,要控制的不[发送端]而是[接收端]
//接受端
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