在服务端和客户端之间既有接收又有发送的情况下,不要过早的关闭输入/出流。
如下:
服务端的IO流有:
- 输出到磁盘的输出流1
- 从客户端读取的输入流2
- 向客户端输出的输出流3
客户端的IO流有:
- 从磁盘读取的输入流4
- 输出到服务端的输出流5
- 从服务端读取的输入流6
服务端接收完客户端发送的图片后,可以关闭输出到磁盘的输出流,但是不要直接关闭接收客户端的输入流,即使已经接收完了。
同样,客户端发送完图片后,可以关闭从磁盘读取的输入流,但是不要关闭输出到服务端的输出流,即使已经发送完了。
否则,服务端或客户端会报错: Socket is closed。
猜测原因是不关闭IO流的话会阻塞另一端,使其不提前结束进程。
如下所示:服务端接收完图片向客户端发送“收到图片”,如果客户端此时已经关闭了输出流5,那么服务端发送完就可以直接关闭socket,结束进程了。而此时客户端可能还没有接受完“收到图片”,所以报错。而客户端在接收完“收到图片”后再关闭输出流5,服务端由于等待输入流2而阻塞,不会关闭socket,保证了客户端顺利接收。
初次学习,理解不深刻,如果有大佬能替我解惑不胜感激~!
// 服务端
public class TCPFileUploadServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
String file_path = "tarimg\\2.jpg";
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file_path));
int readLen = 0;
byte[] buf = new byte[1024];
while((readLen = bis.read(buf))!=-1){
bos.write(buf,0,readLen);
}
bos.flush();
bos.close();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write("收到图片");
bw.newLine();
bw.flush();
socket.shutdownOutput();
bis.close();
bw.close();
socket.close();
serverSocket.close();
System.out.println("已发送");
}
}
//客户端
public class TCPFileUploadClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(),9999);
String file_path = "srcimg\\1.jpg";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file_path));
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
byte[] buf = new byte[1024];
int readLen = 0;
while((readLen = bis.read(buf))!=-1){
bos.write(buf,0,readLen);
}
bos.flush();
bis.close();
socket.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String s = br.readLine();
System.out.println(s);
bos.close();
br.close();
socket.close();
}
}