我的本地机器上运行着服务器和客户端应用程序。客户端获取文件,更改它并发送到服务器,如果文件正确,则服务器响应。客户端执行多次,一次发送一个文件。我从客户端发送了两个文件,在第二个文件上我得到了连接重置
服务器片段:
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();
引发连接重置异常。
您的代码创建一个新的ServerSocket
,然后为它处理的每个请求关闭创建的服务器套接字。代码不使用同一个ServerSocket
实例来处理多个请求。
连接重置失败似乎是因为这个原因,因为当第二个请求正在创建与服务器的套接字连接时,现有的ServerSocket
已关闭并在同一端口上重新创建,从而导致连接被重置。首先尝试ServerSocket
在 while 循环之外取出创建。
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()
(或从它派生的流)的连接获得的信息会传递给单独的线程进行处理,这与串行处理请求的代码不同。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句