Java套接字:将文件发送到服务器后,无法向客户端发送响应

时间:2019-07-07 11:34:14

标签: java arrays sockets

我正在使用Java Socket将文件发送到服务器,然后得到响应。问题是每次我尝试从服务器读取响应时,都会使服务器的文件读取部分挂起。我真的需要您的帮助吗?

这是服务器代码:

ServerSocket server = new ServerSocket(PORT);
Socket client = server.accept();
BufferedInputStream netInStream = new BufferedInputStream(client.getInputStream());
BufferedOutputStream netOutStream = new BufferedOutputStream(client.getOutputStream());

String outFileName = "output/test";
File outputFile = new File(outFileName);
if (!outputFile.exists()) {
    outputFile.getParentFile().mkdirs();
}
FileOutputStream fileOutStream = new FileOutputStream(outputFile);
BufferedOutputStream bufOutStream = new BufferedOutputStream(fileOutStream);

// read file from client and save
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = netInStream.read(buffer)) > 0) {
    bufOutStream.write(buffer, 0, bytesRead);
    bufOutStream.flush();
    Log.line("Bytes read: " + bytesRead);
}
// clean up file IO
// ...

// send response to client
netOutStream.write("File received by server".getBytes());
netOutStream.flush();

// clean up network IO
// ...

客户代码:

Socket client = new Socket(DOMAIN_SERVER, PORT_SERVER);
BufferedOutputStream netOutStream = new BufferedOutputStream(client.getOutputStream());
BufferedInputStream netInStream = new BufferedInputStream(client.getInputStream());

String inFileName = "input/test";
File file = new File(inFileName);
if (!file.exists()) {
    client.close();
    return;
}
FileInputStream fileInSream = new FileInputStream(file);
BufferedInputStream bufInStream = new BufferedInputStream(fileInSream);

// read and send file to server
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = bufInStream.read(buffer)) > 0) {
    netOutStream.write(buffer, 0, bytesRead);
    netOutStream.flush();
    Log.line("Bytes sent: " + bytesRead);
}
// clean up file IO
// ...

// read response from server
StringBuilder res = new StringBuilder();
byte[] charBuf = new byte[128];
int msgBytesRead = 0;
while ((msgBytesRead = netInStream.read(charBuf)) > 0) {
    res.append(new String(charBuf, 0, msgBytesRead));
}
Log.line(res.toString());

// clean up network IO
// ...

流程是,客户端向服务器发送文件,服务器读取文件并将其保存到本地存储,然后服务器向客户端发送响应字符串,客户端读取响应并将其打印在屏幕上。

如果代码如上,则服务器将不会退出while循环并挂起,因此客户端第二个while循环也不会读取任何内容并挂起。 但是,如果我在第二个while循环中注释/删除客户端,则两个程序都将运行并且不会发生挂起。文件传输也成功。

1 个答案:

答案 0 :(得分:1)

您的期望是,一旦服务器发送完文件,read将不返回任何数据。这种期望是错误的。 read仅在服务器已关闭TCP连接并且您显示的flush不会关闭连接但仅确保所有缓冲的数据均已写入TCP连接的情况下不返回任何数据。

这意味着服务器在flush之后仍可以发送更多数据,这就是为什么您的客户端挂在read上并等待更多数据的原因。