该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-07-01
茅塞顿开,多谢楼主
|
|
返回顶楼 | |
发表时间:2011-07-01
很奇怪为什么head和body要分开写,直接write(head+body) 不就可以了吗,实在不行用bufferedWriter(),然后flush一下。
|
|
返回顶楼 | |
发表时间:2011-07-01
最后修改:2011-07-01
引用 。。。。。。 当你的应用不是这种连续的请求——应答模型,而是需要实时地单向发送很多小数据的时候或者请求是有间隔的,则应该禁用nagle算法来提高响应性。一个最明显是例子是telnet应用,你总是希望敲入一行数据后能立即发送给服务器,然后马上看到应答,而不是说我要连续敲入很多命令或者等待200ms才能看到应答。 上面是我对nagle算法和delayed ack的理解和测试,有错误的地方请不吝赐教 谈谈我的理解: 1.客服端在发送数据报文后,如果由于delayed ack,可能导致客服端等待ack超时,会重发数据报文 2.服务器端在在进行delayed ack时首先会看有没有数据和ack一起发送,如果没有数据需要发送,ack会立即发送到客服端 3.另外tcp协议会根据数据报文的大小来进行报文切片,然后发送,服务端的ack是和这些报文片是相关的,这个间接也会影响网络传输的性能哦 不知道理解对不对,呵呵 |
|
返回顶楼 | |
发表时间:2011-07-01
kakaluyi 写道 很奇怪为什么head和body要分开写,直接write(head+body) 不就可以了吗,实在不行用bufferedWriter(),然后flush一下。
是否立即发送? |
|
返回顶楼 | |
发表时间:2011-07-02
用java Socket没有对Socket的OutputStream/InputStream直接操作的,前面都要封装个BufferedOutputStream/BufferedInputStream。
TCP Delay不过就是要解决小数据合并的问题,这个问题完全可以在java里自己解决,而且效果更好。 Socket的服务器编程里几乎一律关掉TCP Delay。 |
|
返回顶楼 | |
发表时间:2011-07-02
plus 网络程序里 算法霸道纵横.....
|
|
返回顶楼 | |
发表时间:2011-07-02
最后修改:2011-07-02
taolei0628 写道 用java Socket没有对Socket的OutputStream/InputStream直接操作的,前面都要封装个BufferedOutputStream/BufferedInputStream。
TCP Delay不过就是要解决小数据合并的问题,这个问题完全可以在java里自己解决,而且效果更好。 Socket的服务器编程里几乎一律关掉TCP Delay。 人家的内核里做的事情,你能在应用层做的更好?没开玩笑吧。我测试的结果也证明开启比不开启更好。 内核会根据各种因素做出判断是否立即发送数据,加上拥塞控制之类,nagle算法只是其中一个考虑因素。当然,应用层可以做的事情是每次发送尽量都以发送缓冲区的大小写入数据。 这里的例子是故意设计出来,看看nagle+delayed ack会造成什么后果,也告诉大家避免write-write-read这样的编程方式。 |
|
返回顶楼 | |
发表时间:2011-07-02
dennis_zane 写道 taolei0628 写道 用java Socket没有对Socket的OutputStream/InputStream直接操作的,前面都要封装个BufferedOutputStream/BufferedInputStream。
TCP Delay不过就是要解决小数据合并的问题,这个问题完全可以在java里自己解决,而且效果更好。 Socket的服务器编程里几乎一律关掉TCP Delay。 人家的内核里做的事情,你能在应用层做的更好?没开玩笑吧。我测试的结果也证明开启比不开启更好。 内核会根据各种因素做出判断是否立即发送数据,加上拥塞控制之类,nagle算法只是其中一个考虑因素。当然,应用层可以做的事情是每次发送尽量都以发送缓冲区的大小写入数据。 这里的例子是故意设计出来,看看nagle+delayed ack会造成什么后果,也告诉大家避免write-write-read这样的编程方式。 你也太迷信内核了吧。谁能掌握更多的细节信息,谁才能优化得更好,而不是内核就一定比应用更好。 Socket上是流化的数据,而实际通讯数据时要有分隔的。内核能知道数据流上哪里是一个完整的请求而需要立即发送,哪里不是完整的请求需要合并吗?内核只能靠猜测或适当的延时来合并数据,这势必会照成小数据块请求被拖延一定时间。而应用作为数据的发送者对这些细节最清楚,在需要合并的时候它自己合并,该需要立即发送的时候,也不会有延迟。 你测试的结果也可能测试程序本身需要靠tcp delay优化,自己并没有做关闭tcp delay后的优化。 |
|
返回顶楼 | |
发表时间:2011-07-02
taolei0628 写道 dennis_zane 写道 taolei0628 写道 用java Socket没有对Socket的OutputStream/InputStream直接操作的,前面都要封装个BufferedOutputStream/BufferedInputStream。
TCP Delay不过就是要解决小数据合并的问题,这个问题完全可以在java里自己解决,而且效果更好。 Socket的服务器编程里几乎一律关掉TCP Delay。 人家的内核里做的事情,你能在应用层做的更好?没开玩笑吧。我测试的结果也证明开启比不开启更好。 内核会根据各种因素做出判断是否立即发送数据,加上拥塞控制之类,nagle算法只是其中一个考虑因素。当然,应用层可以做的事情是每次发送尽量都以发送缓冲区的大小写入数据。 这里的例子是故意设计出来,看看nagle+delayed ack会造成什么后果,也告诉大家避免write-write-read这样的编程方式。 你也太迷信内核了吧。谁能掌握更多的细节信息,谁才能优化得更好,而不是内核就一定比应用更好。 Socket上是流化的数据,而实际通讯数据时要有分隔的。内核能知道数据流上哪里是一个完整的请求而需要立即发送,哪里不是完整的请求需要合并吗?内核只能靠猜测或适当的延时来合并数据,这势必会照成小数据块请求被拖延一定时间。而应用作为数据的发送者对这些细节最清楚,在需要合并的时候它自己合并,该需要立即发送的时候,也不会有延迟。 你测试的结果也可能测试程序本身需要靠tcp delay优化,自己并没有做关闭tcp delay后的优化。 再补充上面的问题,为什么文章作者提到JavaNIO没有那样的问题?socket内核里收发数据也区分socket是同步的还是异步的吗?我甚至不确定系统内核有没有线程的概念。 |
|
返回顶楼 | |
发表时间:2011-07-02
taolei0628 写道 taolei0628 写道 dennis_zane 写道 taolei0628 写道 用java Socket没有对Socket的OutputStream/InputStream直接操作的,前面都要封装个BufferedOutputStream/BufferedInputStream。
TCP Delay不过就是要解决小数据合并的问题,这个问题完全可以在java里自己解决,而且效果更好。 Socket的服务器编程里几乎一律关掉TCP Delay。 人家的内核里做的事情,你能在应用层做的更好?没开玩笑吧。我测试的结果也证明开启比不开启更好。 内核会根据各种因素做出判断是否立即发送数据,加上拥塞控制之类,nagle算法只是其中一个考虑因素。当然,应用层可以做的事情是每次发送尽量都以发送缓冲区的大小写入数据。 这里的例子是故意设计出来,看看nagle+delayed ack会造成什么后果,也告诉大家避免write-write-read这样的编程方式。 你也太迷信内核了吧。谁能掌握更多的细节信息,谁才能优化得更好,而不是内核就一定比应用更好。 Socket上是流化的数据,而实际通讯数据时要有分隔的。内核能知道数据流上哪里是一个完整的请求而需要立即发送,哪里不是完整的请求需要合并吗?内核只能靠猜测或适当的延时来合并数据,这势必会照成小数据块请求被拖延一定时间。而应用作为数据的发送者对这些细节最清楚,在需要合并的时候它自己合并,该需要立即发送的时候,也不会有延迟。 你测试的结果也可能测试程序本身需要靠tcp delay优化,自己并没有做关闭tcp delay后的优化。 再补充上面的问题,为什么文章作者提到JavaNIO没有那样的问题?socket内核里收发数据也区分socket是同步的还是异步的吗?我甚至不确定系统内核有没有线程的概念。 哦,我就是文章作者。NIO怎么会没有这样的问题,问题同样存在。 内核并不是靠猜测来决定是否合并数据,这完全有一套规则,你要不知道可以看TCP/IP卷一或者RFC。应用层的合并有好处,但不能替代nagle算法,事实上应用自己的合并并不会直接影响到内核的分片,应用能做的事情很有限,就是我刚才提到,以发送缓冲区的大小发送数据从而提高吞吐量。 人家协议栈考虑的因素比你全面,合并不合并自有一套规则,目的就是提高网络的利用率。当然,你要说你比搞TCP协议和协议栈实现的人牛叉,那我还能说啥? 另外,我的测试就是基于NIO,我文章里提了,就是以xmemcached这个实际应用做压测看到的结果。 |
|
返回顶楼 | |