Socket通讯使用遇到(BufferedReader||Write)(Output||InputStream)(Object Input||Output Stream)的问题/阻塞/空

使用 BufferedReader 和 BufferedWrite 接收读取数据,用 readLine 无法接受数据,一直等待的解决方案:

        1.因为BufferedReader#readLine检测读取完一行必须是通过检测换行符才判断一行读取完成,所以写数据就要加上"\r\n",也可用newLine()方法添加

        2.写完数据后是否调用 flush() 方法冲水

参考:java socketclient 换行_Java Socket/SocketChannel通信/换行/问题/接收不到/消息_weixin_39518002的博客-CSDN博客

使用 OutputStream 和 InputStream "程序不等待" 的解决方案:

//我曾经写过这样一个读取输入流的代码,本意是好的,new 出的数组空间可以根据输入字节大小生成
InputStream is = s.getInputStream();
byte [] bs = new byte[is.available()];
is.read(bs);

        1.上面的写法虽然不会造成读取时阻塞,但是 available 大概率读取到的是0,因为是网络通讯,数据并不会那么快的传输返回,这样子is.read()就会出现一系列问题,如:

        1.越界(可能出现)        2.空指针(可能出现)        3.不报错读取空数据(已出现)

代码

Socket通讯使用遇到(BufferedReader||Write)(Output||InputStream)(Object Input||Output Stream)的问题/阻塞/空_第1张图片

读取空值的原因:

Socket通讯使用遇到(BufferedReader||Write)(Output||InputStream)(Object Input||Output Stream)的问题/阻塞/空_第2张图片

调试查看源码分析的出:

直接调用read()方法,源码会先判断是否有读到的东西,有则写入,无则阻塞等待,但是

先调用 available() 方法,再调用 read()方法 则会判断已存在数据,无阻塞,写入0

解决的最好方法就是: 

1.使用BufferedReader读取        2.固定数组长度       

3.设置一个循环卡住 available(),读取到有用信息再继续

int num = 0;
while (num==0){
    num = in.available();
}

参考:

Socket传输信息或文件_YueQiong的博客-CSDN博客_socket文件传输

Socket通信时客户端和服务端使用ObjectInputStream与ObjectOutputStream的顺序问题

        不按照程序指定顺序将会造成服务端和客户端两边同时阻塞

服务端顺序:

ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());

客户端顺序:

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());

原因:

仔细看ObjectInputStream的API

Socket通讯使用遇到(BufferedReader||Write)(Output||InputStream)(Object Input||Output Stream)的问题/阻塞/空_第3张图片 

        第一段的意思是,创建一个从指定的InputStream读取的ObjectInputStream,序列化的流的头是从这个Strem中读取并验证的。此构造方法会一直阻塞直到相应的ObjectOutputStream已经写入并刷新头。

        所以上述代码执行后会都阻塞,如果将创建ObjectInputStream的顺序修改成其他的顺序,便可正常通信。


原因部分参考:关于Java中Socket通信时使用ObjectInputStream与ObjectOutputStream的顺序问题_gary0917的博客-CSDN博客

你可能感兴趣的:(Java,java)