您的位置:首页 > Web前端

socket编程BufferReader.readLine()遇到的坑

2016-05-18 17:57 351 查看
socket编程BufferReader.readLine()遇到的坑

最几天公司马上要上手一个项目需要用到Java对接硬件, 就是个停车场的智能管理项目,其实要与硬件进行通信, 听说jboos netty 不错。 就研究了两天 没研究出什么成果来, 可能是自己能力不足吧, 但看到有人说过《netty权威指南》这本书, 所以下载看了看, 因为感觉现在百度上关于entty的文章资料还不多, 也不够全面仔细。 好了 步入正题、 在看第二章作者介绍同步阻塞IO的时候, 有一个例子。 书上例子是这样的

public class TimeServer {

public static void main(String[] args) throws IOException {
int port  = 8085;
ServerSocket server = null;
try {
// 创建服务
server = new ServerSocket(port);
System.out.println("The time server is start  in port :"+port);
Socket socket = null;
while(true){
// 监听
socket = server.accept();
new Thread(new TimeServerHandler(socket)).start();
}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
if(server != null){
server.close();
System.out.println("The time server is close!");
server = null;
}
}
}

}

class TimeServerHandler implements Runnable{

private Socket socket = null;

public  TimeServerHandler(Socket socket ) {
this.socket = socket;
}

@Override
public void run() {
// 字符读取缓存流
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream()),true);
String currentTime = null;
String body = null;
while(true){
body = in.readLine();
if(body == null){
break;
}
System.out.println("The time server receive order:"+body);
// 如果客户端发来的指令为:QUERY TIME ORDER 则返回当前时间, 否则返回 BAD ORDER 指令无效
currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body)?new Date().toString():"BAD ORDER";
}
// 响应客户端
out.print(currentTime);
} catch (Exception e) {
e.printStackTrace();
} finally{
if(in != null){
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
in = null;
}
if(out != null){
out.close();
out = null;
}
if(socket != null){
try {
this.socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.socket = null;
}

}
}

}

public class TimeClient {

public static void main(String[] args) {

Socket socket  = null;
BufferedReader in = null;
PrintWriter out = null;
try {
socket = new Socket("rascal-guo", 8085);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true);
out.println("QUERY TIME ORDER");
System.out.println("send order to server succeed!");
String resp = in.readLine();
System.out.println("Now time is : "+resp);
} catch (Exception e) {
e.printStackTrace();
} finally{
if(out != null){
out.close();
out = null;
}
if(in != null){
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
in = null;
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
socket = null;
}
}
}
}


运行的时候却出现了问题,TimeServerHandler类body = in.readLine(); 这行代码第一次执行的时候没问题,但第二次执行时候 却到这阻塞了,一直就没往下执行。经过网上搜索,各种说法收集一下,然后凭着自己对代码的灵感进行了逐步的试修改,首先是在TimeClient类中out.println(“QUERY TIME ORDER\n”); 后面加了个换行符, 因为in.readLine()是逐行读取(根据换行符),可能服务端没读取到换行符所以一直在读取(………好像有点说不通)。 再次跑下服务端和客户端。发现服务端readLine()方法不在阻塞。但是第二次他还会读取“”空字符串出来,不能明白。既然不影响 程序顺利执行就不管啦, 第一个问题解决了,但是第二个问题又来了。 客户端打印服务端的响应是null,Now time is : null。 百思不得其解。根据我之前看的资料。感觉性的往服务端out.print(currentTime);的后面加上了out.flush(); 问题成功就解决了。 至于为什么,由于小弟知识浅薄,没研究过源码,故不能深刻的理解,以上如有理解错误,望指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息