转自:
https://bbs.youkuaiyun.com/topics/70302893?list=lz
两台公众网上的机器用PCAnywhere连接起来后,用PCAnywhere传输文件,速度能达到约50K Byte/s的速度传输文件,一个700K的文件,也就是几秒钟能够传输完成。
自己用MFC写程序连接,采用tcp/ip协议建立连接,使用了CAsyncSocket建立连接, SOCK_STREAM类型。发送方,不停地发送数据,或者在CAsyncSocket::OnSend中发送数据,接受方在OnReceive中接受数据,速度爆满,顶多有几百字节/秒的传输速度。 如果发送方的报文,也就是每一次CAsyncSocket::Send的报文大小,设置为1K以上,那么,很可能就堵塞了:很长时间过不来,然后突然间可能过来了。 如果发送方的报文,也就是每一次CAsyncSocket::Send的报文大小,设置为256或者更小,则报文能断断续续过来,可是仍然爆慢。 另外发送方的发送缓冲区,如果设置为很大,则大多数报文反而被堵塞。 自己写程序实现通信,传输700k的文件,起码需要半个多小时。相比PcAnywhere的传输速度,一个天上一个地下,可是,不知道为什么? 请问,可能原因是什么,如何解决? 谢谢! |
谢谢大家关心!
事实上,我也正在希望我的程序有问题,主要是我实在不知道问题在那里。 测试程序很简单,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; } } } } |