Java 服务器-客户端连接重置
Java Server-Client Connection reset
我的本地计算机上有服务器和客户端应用程序 运行。
客户端获取文件,对其进行更改并发送到服务器,然后服务器在文件正确时做出响应。客户端多次执行,一次发送一个文件。
我从客户端发送了两个文件,在第二个文件上我收到 Connection reset
服务器代码段:
private void initServer() throws IOException {
while (true) {
ServerSocket server = new ServerSocket(55555);
Socket fromclient = server.accept();
InputStream sin = fromclient.getInputStream();
OutputStream sout = fromclient.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
String line = in.readUTF();
if (line.equals("new file")) {
long fileSize = in.readLong();
tempSavedFile = new File("/home/evgeniy/Files/Downloads/temp");
tempSavedFile.createNewFile();
try (FileOutputStream fos = new FileOutputStream(tempSavedFile)) {
int t;
for (int i = 0; i < fileSize; i++) {
t = sin.read();
fos.write(t);
}
}
if (checkPadding(tempSavedFile)) {
out.writeInt(PADDING_OK_RESPONSE);
} else {
out.writeInt(PADDING_ERROR_RESPONSE);
}
out.flush();
}
out.close();
in.close();
sout.close();
sin.close();
fromclient.close();
server.close();
}
}
在for循环中调用新线程的客户端class
for (byte i = 0; i < 2; i++) {
Callable callable = new FileSender(tempFile);
FutureTask<Integer> ftask = new FutureTask<>(callable);
Thread thread = new Thread(ftask);
thread.start();
int response = 3244;
try {
response = ftask.get();
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(FXMLController.class.getName()).log(Level.SEVERE, null, ex);
}
putMessage(String.valueOf(response));
客户端可调用线程:
public Integer call() throws Exception {
Socket socket = new Socket(address, serverPort);
InputStream sin = socket.getInputStream();
OutputStream sout = socket.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
out.writeUTF("new file");
out.flush();
out.writeLong(file.length);
out.flush();
sout.write(file);
sout.flush();
System.out.println(socket.isConnected());
int response = in.readInt();
System.out.println("--------RESP="+response);
out.close();
in.close();
sin.close();
sout.close();
socket.close();
return response;
}
如您所见,我发送了两个文件,并在客户端应用程序上获得了此控制台输出:
true
--------RESP=200
true
ноя 20, 2018 5:16:36 PM com.evgeniy_mh.paddingoracle.FXMLController SendFileToServer
SEVERE: null
java.util.concurrent.ExecutionException: java.net.SocketException: Connection reset
另外,我不明白为什么socket可以,但是
int response = in.readInt();
引发连接重置异常。
您的代码创建了一个新的 ServerSocket
并稍后为它处理的每个请求关闭创建的服务器套接字。该代码不使用相同的 ServerSocket
实例来处理多个请求。
连接重置失败似乎是因为这个,因为当第二个请求正在创建与服务器的套接字连接时,现有的ServerSocket
被关闭并在同一端口上重新创建导致连接被重置。首先尝试在 while 循环之外取出 ServerSocket
创建。
private void initServer() {
try (ServerSocket server = new ServerSocket(5555)) {
while (true) {
Socket fromclient = server.accept();
... // remaining code
fromclient.close();
}
} catch (IOException ioe) {
// handle failures
}
}
try-with-resources
处理 AutoCloseable
服务器套接字上的 .close()
调用。
另请注意,请求将在代码中的单个线程上连续处理。通常,从 ServerSocket#accept()
(或从它派生的流)获得的连接的 Socket
被传递到单独的线程进行处理,这与串行处理请求的代码不同。
我的本地计算机上有服务器和客户端应用程序 运行。 客户端获取文件,对其进行更改并发送到服务器,然后服务器在文件正确时做出响应。客户端多次执行,一次发送一个文件。 我从客户端发送了两个文件,在第二个文件上我收到 Connection reset
服务器代码段:
private void initServer() throws IOException {
while (true) {
ServerSocket server = new ServerSocket(55555);
Socket fromclient = server.accept();
InputStream sin = fromclient.getInputStream();
OutputStream sout = fromclient.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
String line = in.readUTF();
if (line.equals("new file")) {
long fileSize = in.readLong();
tempSavedFile = new File("/home/evgeniy/Files/Downloads/temp");
tempSavedFile.createNewFile();
try (FileOutputStream fos = new FileOutputStream(tempSavedFile)) {
int t;
for (int i = 0; i < fileSize; i++) {
t = sin.read();
fos.write(t);
}
}
if (checkPadding(tempSavedFile)) {
out.writeInt(PADDING_OK_RESPONSE);
} else {
out.writeInt(PADDING_ERROR_RESPONSE);
}
out.flush();
}
out.close();
in.close();
sout.close();
sin.close();
fromclient.close();
server.close();
}
}
在for循环中调用新线程的客户端class
for (byte i = 0; i < 2; i++) {
Callable callable = new FileSender(tempFile);
FutureTask<Integer> ftask = new FutureTask<>(callable);
Thread thread = new Thread(ftask);
thread.start();
int response = 3244;
try {
response = ftask.get();
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(FXMLController.class.getName()).log(Level.SEVERE, null, ex);
}
putMessage(String.valueOf(response));
客户端可调用线程:
public Integer call() throws Exception {
Socket socket = new Socket(address, serverPort);
InputStream sin = socket.getInputStream();
OutputStream sout = socket.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
out.writeUTF("new file");
out.flush();
out.writeLong(file.length);
out.flush();
sout.write(file);
sout.flush();
System.out.println(socket.isConnected());
int response = in.readInt();
System.out.println("--------RESP="+response);
out.close();
in.close();
sin.close();
sout.close();
socket.close();
return response;
}
如您所见,我发送了两个文件,并在客户端应用程序上获得了此控制台输出:
true
--------RESP=200
true
ноя 20, 2018 5:16:36 PM com.evgeniy_mh.paddingoracle.FXMLController SendFileToServer
SEVERE: null
java.util.concurrent.ExecutionException: java.net.SocketException: Connection reset
另外,我不明白为什么socket可以,但是
int response = in.readInt();
引发连接重置异常。
您的代码创建了一个新的 ServerSocket
并稍后为它处理的每个请求关闭创建的服务器套接字。该代码不使用相同的 ServerSocket
实例来处理多个请求。
连接重置失败似乎是因为这个,因为当第二个请求正在创建与服务器的套接字连接时,现有的ServerSocket
被关闭并在同一端口上重新创建导致连接被重置。首先尝试在 while 循环之外取出 ServerSocket
创建。
private void initServer() {
try (ServerSocket server = new ServerSocket(5555)) {
while (true) {
Socket fromclient = server.accept();
... // remaining code
fromclient.close();
}
} catch (IOException ioe) {
// handle failures
}
}
try-with-resources
处理 AutoCloseable
服务器套接字上的 .close()
调用。
另请注意,请求将在代码中的单个线程上连续处理。通常,从 ServerSocket#accept()
(或从它派生的流)获得的连接的 Socket
被传递到单独的线程进行处理,这与串行处理请求的代码不同。