要求
客户端向服务端传输一个文件,服务端接受文件之后将文件保存在本地,并向客户端返回 接收成功 的信息,客户端接收到信息之后将信息打印到控制台上。
分析
客户端向服务器传输文件,实质上就是将本地的文件变成文件流,然后写入到Socket的OutputStream中
然后服务器将OutputStream写入到文件流中,进行保存文件的操作。
服务端向客户端返回信息,只用拿到客户端的Socket 然后把返回的信息写入OutputStream中就可以了。
客户端接收服务端返回的信息,只需要在传输完文件之后去获取客户端Socket的InputStream(会一直等待服务器),然后把流里面的内容转成字符串就可以了。
注意
由于数据是在网络中传输的,服务端读取流的时候是无法while_((_len = inputStream.read_(_buffer_)) _!= -1_)_ 来判断流是否结束的(本地文件可以有EOF),因此,需要我们在客户端传输数据结束之后,给服务端一个结束的信号socket.shutdownOutput_()_
代码
package test21;import org.junit.Test;import java.io.*;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;/*** Created By Intellij IDEA** @author Xinrui Yu* @date 2021/12/5 21:10 星期日*/public class SocketServerTest2 {@Testpublic void client(){Socket socket = null;FileInputStream fileInputStream = null;BufferedInputStream bufferedInputStream = null;InputStream inputStream = null;try{fileInputStream = new FileInputStream("img.jpg");bufferedInputStream = new BufferedInputStream(fileInputStream);InetAddress ip = InetAddress.getByName("127.0.0.1");socket = new Socket(ip,8080);OutputStream outputStream = socket.getOutputStream();byte[] buffer = new byte[1024];int len;while((len = bufferedInputStream.read(buffer)) != -1){outputStream.write(buffer,0,len);}socket.shutdownOutput();inputStream = socket.getInputStream();byte[] buffer2 = new byte[1024];int len2;while((len2 = inputStream.read(buffer2)) != -1){String str = new String(buffer2,0,len2);System.out.print(str);}}catch (IOException e){e.printStackTrace();}finally {if(bufferedInputStream != null){try {bufferedInputStream.close();} catch (IOException e) {e.printStackTrace();}}if(inputStream != null){try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}if(socket != null){try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}@Testpublic void server(){ServerSocket serverSocket = null;BufferedOutputStream bufferedOutputStream = null;InputStream inputStream = null;OutputStream outputStream = null;try{FileOutputStream fileOutputStream = new FileOutputStream("SocketImage.png");bufferedOutputStream = new BufferedOutputStream(fileOutputStream);serverSocket = new ServerSocket(8080);Socket clientSocket = serverSocket.accept();inputStream = clientSocket.getInputStream();int len;byte[] buffer = new byte[1024];while((len = inputStream.read(buffer)) != -1){bufferedOutputStream.write(buffer,0,len);}System.out.println("成功收到来自:" + clientSocket.getInetAddress().getHostAddress() + "的图片");outputStream = clientSocket.getOutputStream();outputStream.write("照片已收到!谢谢你!".getBytes());Thread.sleep(3000);}catch (IOException | InterruptedException e){e.printStackTrace();}finally {if(bufferedOutputStream != null){try {bufferedOutputStream.close();} catch (IOException e) {e.printStackTrace();}}if(inputStream != null){try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}if(outputStream != null){try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}if(serverSocket != null){try {serverSocket.close();} catch (IOException e) {e.printStackTrace();}}}}}
运行
服务端等待客户端的连接
客户端启动之后会等待服务端返回信息
服务端3s(手动设置的)之后,将返回成功的信息返回给客户端,客户端接收到信息之后打印到控制台,然后程序才会截止。
