gpt4 book ai didi

Java Socket 不等待接收字节

转载 作者:行者123 更新时间:2023-11-30 11:17:18 27 4
gpt4 key购买 nike

我在 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);
}

句柄方法是:

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
...

它不会停止。

你能告诉我如何解决这个问题吗?

最佳答案

您描述的情况发生在客户端关闭连接时(即最后关闭套接字/流),而只是客户端没有发送任何东西(如果客户端空闲但仍处于连接状态,服务器不会打印任何内容)。

这是因为 InputStream 类的方法 read 在流/连接关闭时不会抛出异常,而只是返回值 -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 ...

你的代码中的另一个问题是我猜是一个错误,但我不确定,否则你不应该能够运行你的代码(但我不能说,因为你复制的代码不完整)。错误是当您调用启动方法 MyClass.start(); 时:由于此方法不是静态的,因此您必须在您创建的 MyClass 类的对象上调用它实例化之前的行,即以这种方式调用方法:elevator.start();

希望对您有所帮助。

关于Java Socket 不等待接收字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24430179/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com