我在本地计算机上运行服务器和客户端应用程序。 客户端获取文件,将其更改并发送到服务器,然后服务器响应该文件是否正确。客户端执行多次,一次发送一个文件。 我从客户端发送了两个文件,在第二个文件上,我得到了连接重置
服务器摘要:
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循环中调用新线程的客户端类
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
另外,我不明白为什么套接字可以,但是
int response = in.readInt();
引发连接重置异常。
答案 0 :(得分:0)
您的代码创建一个新的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
处理.close()
服务器套接字上的AutoCloseable
调用。
另外,请注意,请求将在代码中的单个线程上顺序处理。通常,与从Socket
(或从其派生的流)的连接中获得的ServerSocket#accept()
会传递到单独的线程进行处理,这与您的代码以串行方式处理请求不同。