怎样提高socket 的传输效率?欢迎讨论,Up有分
最近做socket传输程序,发觉在internet上传输效率非常低下,我方为10兆ddn,我有几个客户,一个客户的网络非常好,采用的是两条联通的8兆bit等宽的光纤网,我曾经试过在网上的下载速度就能到达1兆,但我用我的socket传输软件传输数据到我公司只有可怜的20K有时还不到,在晚上没有其它人占用网络的情况下也只能达到100K,怀疑是我的程序的问题我换用ftp软件传输,速度跟我的差不多,我又找了一个上传速度为512k的adsl,发觉传输速度并不慢,也能达到20K,没有人用时能达到40几k.
我开始郁闷了,通过与客户的网络人员交换意见,得出结了,是我的程序的网络使用率不高,我看了我的程序,我是用delphi自带socket控件传输的,方式为非阻塞,每次传输1024以上字节.我调试时发觉只要发送
超过1024,发送失败的时候就会很多.程序就需要重新发送.
不知到各位在做类似程序的弟兄们有没有遇到类似问题?一句话,怎样加快传输效率????
问题点数:100、回复次数:39Top
1 楼wofan(我烦)回复于 2004-09-01 22:05:50 得分 0
多开几个Port呢?一个文件分成几部分传Top
2 楼yjmao2003(小游)回复于 2004-09-01 23:39:45 得分 0
在传输过程中用Tstream类,及其子类来接收和发送文件Top
3 楼halfdream(哈欠)回复于 2004-09-02 00:17:25 得分 0
呵呵..恕我直言...你代码中有错误,而不仅是效率问题.....
不信可以贴出来.
Top
4 楼SafeF8(A++.NET)回复于 2004-09-02 00:21:36 得分 0
关注ing.........Top
5 楼fengub()回复于 2004-09-02 08:28:01 得分 0
支持Top
6 楼yinweixian(blackyin)回复于 2004-09-02 08:48:47 得分 0
不会很慢的,实在不行就用流传Top
7 楼extcsdn(Studing VB now)回复于 2004-09-02 11:27:00 得分 50
支持 halfdream(哈欠) 的意见Top
8 楼cqzyf(阿牛)回复于 2004-09-02 11:30:25 得分 0
halfdream(哈欠) 你好,又看到你了,关于传输的问题,我问了很多问题了,上传也是你的
回复让我解决了一次只能传输1024字节的问题.我的代码在你上次的回复中已经有了.
在internet上传输效率确实是个问题,任何软件都不可能全部的利用带宽,比如一个公司的
adsl 有的职员在上网,同时也有文件传输程序运行,就会存在互相强带宽的情况.
还有如果我用ftp上传文件,开一个ftp程序传输的速度可能是20K/s,但我开三个ftp程序同时传输每一个程序的传输速度就会是18K/s,加起来为40到50K/s,怎么解释这个原因呢?
再有我发觉在internet上用socket传输,每次传输1024k字节,
Stream1.ReadBuffer(Sendbuf1^, 1024);
li_SendedSize := Socket.SendBuf(Sendbuf1^, 1024);一定不会出现
写buf失败也就是li_SendedSize= -1 的情况,但我如果我一次发送1024以上,就会经常出现
li_SendedSize= -1的情况,所以我每次发送1024还是2048还是4096传输速度并没有明显的改观.
Top
9 楼aiunong(凡)回复于 2004-09-02 11:43:58 得分 0
学习。Top
10 楼cqzyf(阿牛)回复于 2004-09-02 11:47:30 得分 0
To :halfdream(哈欠) 还有按照你所说,不必等待直接写缓冲,可靠性由Tcp/IP协议自己提供,可是如果一旦出现写缓冲失败我就得等待,再去写,也是失败,只有等待客户接收完,将缓冲清空后才能成功!,怎样设置socket得缓冲让它大于8192,我发觉8192好像是最大的了.每次发送必须
小于等于8192字节.Top
11 楼halfdream(哈欠)回复于 2004-09-02 12:27:15 得分 0
要讨论传输效率是个很复杂的....我也会头晕的..呵
有些深入点的东西,我推荐你看'TCP/IP详解',网上有电子版.
先简单说一下,在非阻塞方式下,
Socket.SendBuf(Sendbuf1^, 1024);
你调用它过后,仅仅是在winSock的内部缓存写进了1024字节数据,由SOCKET的协议栈
组织成一定大小的IP包发出.具体组织规则我是不太清楚.不过一点可以确认,大的会
分割,小的可能会合并.
在WINDOWS下,SOCKET可以使用好几种IO方式,这也是能否利用SOCKET效率的因素,
异步选择IO,事件选择IO,重叠IO,完成端口(IOCP).
楼主所用的非阻塞方式,其实是使用异步选择IO方式,它比较易用,但因为它在主线程,
同时又依赖WINDOWS消息,有可能达不到很高的效率.不过...一般来说,也不会有非常悬殊
的差别..
呵呵.我先找一下以前你的贴子..
Top
12 楼hmily1688(没什么好说的)回复于 2004-09-02 14:05:54 得分 0
upTop
13 楼cqzyf(阿牛)回复于 2004-09-02 22:22:29 得分 0
谢谢 halfdream(哈欠) ,希望大家继续讨论
Top
14 楼scapple(七月流火)回复于 2004-09-03 15:29:53 得分 0
to 阿牛:
“怎样设置socket得缓冲让它大于8192,我发觉8192好像是最大的了.每次发送必须
小于等于8192字节.”
是不是说如果对方给我发的socket的包超过8192,后面的东西就会被丢弃掉?Top
15 楼cjf0426(cjf0426)回复于 2004-09-03 15:37:12 得分 0
多线程Top
16 楼netwan(网络菜鸟)回复于 2004-09-04 12:19:26 得分 0
我是这样做的,动态设置socks的sendbuffer
监测当前的网络传输速度
if speed<10k/s then sendbuffer:=8192 (8k)
if speed>=10k/s and speed<40k/s then sendbuffer:=16384 (16k)
if speed>=40k/s then sendbuffer:=32768 (32k)
当然,如果两端的网络带宽都牛的话可以利用多线程来传输。Top
17 楼701701()回复于 2004-09-04 12:30:05 得分 20
我建议你不要使用clientsocket和serversocket组件
用socket API编写的效率会提供很多的!!
本人研究了一下delphi自带的单元文件发现:
delphi的registry类和socket都写的很差
注意是很差,不是一般的差!
所以我编写程序的时候从来不要它们.而是直接调用api
socket的10061问题提问文章已经有3年多了
没有人给出解决办法!
到现在delphi还是不能正常解决
如此常见的问题居然不放在error事件中捕获!
另外delphi自带的注册表类也很差
调用了很多没有必要的单元文件.它占用的资源太多
Top
18 楼chan2chen(蓝忆雨夜)回复于 2004-09-04 23:14:08 得分 0
up
upTop
19 楼qinmaofan(采菊南山下【抵制日货】)回复于 2004-09-05 09:17:28 得分 0
我现在也不用Tregistry单元了,连TBitmap单元都尽量少用。
还是直接用Windows32 API爽阿。Top
20 楼qinmaofan(采菊南山下【抵制日货】)回复于 2004-09-05 09:20:33 得分 0
推荐一个组件 TSimpleTCP,可从www.torry.net下载,免费开源。
这个组件比Delphi自带的socket组件好用,代码简洁。用于非阻塞、多线程非常的爽。不过只支持TCP。Top
21 楼cqzyf(阿牛)回复于 2004-09-06 16:55:32 得分 0
To: scapple(七月流火) 我是在调试时发现的,如果每次发送8192字节的数据,它不是回丢包,而是可能更本就不能写如缓冲,或是自动分成小于8192的字节分别发送Top
22 楼ghy412(用心良苦)回复于 2004-09-06 17:03:40 得分 0
学习Top
23 楼tsk()回复于 2004-12-08 16:48:06 得分 0
很感兴趣,帮你顶!Top
24 楼myshihao()回复于 2004-12-09 16:14:21 得分 0
学习Top
25 楼surpassable()回复于 2004-12-09 17:02:57 得分 0
学习Top
26 楼towsi4(凉光)回复于 2004-12-10 10:08:31 得分 0
upTop
27 楼A_ganfly(阿甘)回复于 2004-12-10 10:19:13 得分 0
学习Top
28 楼XuDunYu(西门吹雪)回复于 2004-12-10 11:25:04 得分 0
支持Top
29 楼wangjintu(万般归一)回复于 2004-12-10 17:02:14 得分 20
个人感觉瓶颈在你程序的发送过程中,非阻塞模式的话是包一个一个排队发送,即使把包设成8192或者更大,还是在一个连接中发送,既然你的网络状况这么好,为什么不用多线程发送Top
30 楼maodelphi(小游)回复于 2004-12-11 18:11:35 得分 0
欢迎广大Delphi爱好者到《delphi专题研讨会》到QQ群7568683
讨论Top
31 楼sunhuiNO1(2B)回复于 2004-12-12 10:46:40 得分 10
个人认为 701701() 的说法不对
TServerSocket和TClientSocket性能还是很不错的,比INDY要很多
至于10061是连接远程服务器失败,我见过很多用DELPHI开发的网络
游戏都是用这套组件做的,一般连续运行几个月都没问题,
至于发送的问题大家没有仔细分析TCP地层的传输机制,根本就没有
必要动态设置发送缓冲的大小,一般我是取8K作为发送缓冲大小
在用猫测试也没有出什么问题,10M大小的文件用猫传输到服务器
也很正常,文件读出来和原来一样。Top
32 楼ahjoe(强哥)回复于 2004-12-12 11:21:02 得分 0
用TServerSocket,与TClientSocket,没有发现有8192的限制,我把包大小设为32K也能正常传输。Top
33 楼sunhuiNO1(2B)回复于 2004-12-12 12:09:10 得分 0
8192是SOCKET缓冲区的大小。
Top
34 楼sunhuiNO1(2B)回复于 2004-12-12 12:11:35 得分 0
你确定你32K数据一次发送出去了?你检查了发送函数的返回值了?
Top
35 楼tsk()回复于 2004-12-29 23:50:18 得分 0
看来我得去好好研究研究去了。。。。。。Top
36 楼zhujunfeng(ericss)回复于 2004-12-30 12:46:08 得分 0
我觉得用api比较好,阻塞模式,多线程,最好作成console,效率更高,包不宜太大,也不能太小,4-8K比较适宜Top
37 楼jeffkxt()回复于 2005-01-05 17:56:51 得分 0
怎么样用Api哦!学习学习Top
38 楼leaber(鹤舞白沙)回复于 2005-01-06 15:17:32 得分 0
呵呵,异步下的传输,用事件模型模型,利用缓冲满通知的原理,单线程这样的效率已经很高了。
再高效一些,用多线程吧。
网络传送是两方面的事,SERVER和CLIENT,所以要考虑双方的带宽和情况。
Top
39 楼gdstyzh01(飞梭流金)回复于 2005-01-06 15:25:12 得分 0
UP,学习Top




