java socket编程学习笔记

来源:互联网 发布:为什么中国网络要翻墙 编辑:程序博客网 时间:2024/06/05 18:36

1.流读取的阻塞和返回值

socket的数据要用流读出来。

然后有很多种读法。有的是只会阻塞和抛出异常的,有的是会返回-1的。

比如dataInputStream.read(),是读一个字符,还没有字符就阻塞着等,连接断了就抛异常。

然后read(byte[] b) ,这个居然,读东西也不一定读到多少,返回值是读到的字节数,有可能是0。然后错误分抛异常和返回-1两种,具体是连接被close掉就会返回-1,直接客户端socket断开会抛出异常。

然后我从read()改用read(byte[] b)的时候,以为它连接断了肯定抛异常,就让返回值是0或-1的时候继续循环。

用自己的客户端测没什么问题,因为我的客户端,都是强行关的,不会close!所以抛异常线程会炸,不会残留。

但是用dpg的超碉客户端,哇,它会close然后重连,我的就死里面了,导致线程数越来越多,效率越来越低,查了好久才发现是这里的问题。


后来用的是readFully(byte[] b),碉得不行,读不满这个b就阻塞,直到读满。也没有返回值,只会抛异常,太碉了。


2.输出流write与flush

我用了一个DataOutputStream来往socket里扔字节流。在windows上正常得不行,往Linux虚拟机上一扔就慢得飞起,qps(每秒处理请求数)低几个数量级。

经过一顿猜想,发现是因为我扔字节流,是多次往里面write,然后flush。

我以为是扔到缓冲区然后flush一下一起扔过去,其实flush的意义是强制把缓冲区剩下的东西都扔过去,而还没flush的时候其实也在传东西了…于是我write了这么多下就耗了很多次TTL。

解决方法:把所有byte[]数组拼成一个大的再write,或者使用BufferedOutputStream代替DataOutputStream,这个是不flush就不发的流。

0 0
原创粉丝点击