我已经在Java中开发了一个套接字,如下所示:
serverSocket = new ServerSocket(port);
System.out.println("Listening in port " + port + " ...");
while (true) {
socket = serverSocket.accept();
System.out.println("Connection has been created.");
handle(socket);
}
handle
方法是:private static void handle(final Socket socket) throws IOException {
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
MyClass elevator = new MyClass(socket, is);
elevator.start();
} catch (IOException io) {
io.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
MyClass是这样的:
class MyClass {
private Socket socket;
private InputStream is;
private PrintWriter out;
private OutputStream ds;
public MyClass(Socket socket, InputStream is) {
this.socket = socket;
this.is = is;
initializeOutputStream(socket);
}
private void initializeOutputStream(Socket socket) {
try {
ds = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() {
while (true) {
try {
int dataLength = 10;
byte[] dataBuffer = new byte[dataLength];
is.read(dataBuffer, 0, dataLength);
// Read and Print cmd.
System.out.println("data:" + DataLayer.byteToString(dataBuffer));
} catch (IOException e) {
e.printStackTrace();
try {
ds.close();
System.out.println("ds closed.");
is.close();
System.out.println("is closed.");
socket.close();
System.out.println("socket closed.");
break;
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
}
当客户端发送数据时,它工作良好,但是当客户端不发送数据时,它打印:
data:0
data:0
data:0
...
它并没有停止。
你能告诉我如何解决这个问题吗?
最佳答案
您描述的情况发生在客户端关闭连接(即套接字关闭/流结束)时,而当客户端不发送任何内容时,而不是(如果客户端处于空闲状态但仍处于连接状态,则服务器不打印任何内容)。
这是因为read
类的方法InputStream
不会在关闭流/连接时而不是引发异常,而只是返回值-1
,因此对于您的实现,while循环只是继续无限运行。
因此,此问题的快速解决方案可以是用以下两个替换您读取流的行:
int endOfStream=is.read(dataBuffer, 0, dataLength);
if(endOfStream==-1) break;
基本上是以这种方式检查流是否已关闭:如果是这种情况,请中断while循环。
另一种解决方案是在while循环之前声明和初始化变量
int endOfStream=0;
,并以这种方式更改while循环条件:int endOfStream = 0; //init to 0 to enter a first time in the loop
while (endOfStream != -1) { //new loop condition
try {
int dataLength = 10;
byte[] dataBuffer = new byte[dataLength];
endOfStream = is.read(dataBuffer, 0, dataLength); //store the return of read
if (endOfStream != -1) { //check if we are not at the end of the stream
// Read and Print cmd.
System.out.println("data:" + dataBuffer[0]);
}
//... the rest of your code ...
您的代码中的另一个问题是我认为是错误,但是我不确定,因为否则您将无法运行代码(但是我不能说,因为您复制的代码不完整)。该错误是当您调用start方法
MyClass.start();
时:由于此方法不是静态的,因此必须在实例化该行之前的MyClass
类的对象上对其进行调用,即以这种方式调用该方法:elevator.start();
希望对您有所帮助。