1.因为BufferedReader#readLine检测读取完一行必须是通过检测换行符才判断一行读取完成,所以写数据就要加上"\r\n",也可用newLine()方法添加
2.写完数据后是否调用 flush() 方法冲水
参考:java socketclient 换行_Java Socket/SocketChannel通信/换行/问题/接收不到/消息_weixin_39518002的博客-CSDN博客
//我曾经写过这样一个读取输入流的代码,本意是好的,new 出的数组空间可以根据输入字节大小生成
InputStream is = s.getInputStream();
byte [] bs = new byte[is.available()];
is.read(bs);
1.上面的写法虽然不会造成读取时阻塞,但是 available 大概率读取到的是0,因为是网络通讯,数据并不会那么快的传输返回,这样子is.read()就会出现一系列问题,如:
1.越界(可能出现) 2.空指针(可能出现) 3.不报错读取空数据(已出现)
直接调用read()方法,源码会先判断是否有读到的东西,有则写入,无则阻塞等待,但是
先调用 available() 方法,再调用 read()方法 则会判断已存在数据,无阻塞,写入0
1.使用BufferedReader读取 2.固定数组长度
3.设置一个循环卡住 available(),读取到有用信息再继续
int num = 0;
while (num==0){
num = in.available();
}
参考:
Socket传输信息或文件_YueQiong的博客-CSDN博客_socket文件传输
不按照程序指定顺序将会造成服务端和客户端两边同时阻塞
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
第一段的意思是,创建一个从指定的InputStream读取的ObjectInputStream,序列化的流的头是从这个Strem中读取并验证的。此构造方法会一直阻塞直到相应的ObjectOutputStream已经写入并刷新头。
所以上述代码执行后会都阻塞,如果将创建ObjectInputStream的顺序修改成其他的顺序,便可正常通信。
原因部分参考:关于Java中Socket通信时使用ObjectInputStream与ObjectOutputStream的顺序问题_gary0917的博客-CSDN博客