案例——TCP上传图片

  • 2019 年 10 月 19 日
  • 筆記

TCP上传图片

  继续做一个TCP的相关案例,在客户端上传一张图片到服务端,服务端收到图片后,给客户端回馈上传成功信息。

实现细节:

  • 对于一些文件的读取,若文件偏大,可以始用缓冲区去读取和写入,可以提高效率
  • 服务端面向的是很多用户,所以必须要开线程来接收
  • 如果同一个用户上传多张图片则有可能文件名重复,所以要对文件名做处理,具体在代码处有注释
  • 客户端图片上传完成后需要给服务端发送结束信息,s.shutdownOutput();
    就像是写入了一个终止符一样

客户端

需要在上传结束的时候写入终止符告诉服务端上传结束,可以双方约定一个终止的符号,也可以用shutdownOutput()方法来传递结束信息

import java.io.BufferedInputStream;  import java.io.BufferedReader;  import java.io.File;  import java.io.FileInputStream;  import java.io.IOException;  import java.io.InputStreamReader;  import java.io.OutputStream;  import java.net.Socket;    public class UploadPicClient {        public static void main(String[] args) throws IOException {          System.out.println("上传图片客户端启动...");            //1、创建socket          Socket s = new Socket("127.233.24.3", 10018);            //2、读取源图片          File picFile = new File("D:\forio\download.jpg");          BufferedInputStream fis = new BufferedInputStream(new FileInputStream(picFile));            //3、目的:socket输出流,发送到服务端          OutputStream out = s.getOutputStream();          byte[] buf = new byte[1024];            int len = 0;          while((len = fis.read(buf)) != -1)          {              out.write(buf, 0, len);          }            //告诉服务端   图片发送完成,不要在等着读了          s.shutdownOutput();            //读取上传成功字样          BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));          String info = in.readLine();          System.out.println(info);            //关闭          fis.close();          s.close();      }  }

服务端

服务端需要多线程接收多个客户的上传信息,对于有可能存在的文件名重复,添加(1)(2)(3)…加以区分

import java.io.BufferedWriter;  import java.io.File;  import java.io.FileOutputStream;  import java.io.IOException;  import java.io.InputStream;  import java.io.OutputStreamWriter;  import java.net.ServerSocket;  import java.net.Socket;    public class UploadPicServer {        public static void main(String[] args) throws IOException {          System.out.println("上传图片服务端启动...");            // 创建ServerSocket          ServerSocket ss = new ServerSocket(10018);            while (true) {              // 获取客户端              Socket s = ss.accept();                // 实现多个客户端并发上传,服务器端必须启动做个线程来完成              new Thread(new UploadPic(s)).start();            }      }  }    class UploadPic implements Runnable {        private Socket s;        public UploadPic(Socket s) {          super();          this.s = s;      }        @Override      public void run() {            try {                String ip = s.getInetAddress().getHostAddress();              System.out.println(ip + "connected...");                // 写图片数据到文件的输出流              File dir = new File("D:\forio\photo");              // 为了避免重名覆盖,通过给重名文件进行编号              int count = 1;              File picFile = new File(dir, ip + "(" + count + ")" + ".jpg");              while (picFile.exists()) {                  count++;                  picFile = new File(dir, ip + "(" + count + ")" + ".jpg");              }                FileOutputStream fos = new FileOutputStream(picFile);                // 读取客户端发来的数据              InputStream in = s.getInputStream();              byte[] buf = new byte[1024];              int len = 0;                while ((len = in.read(buf)) != -1) {                  fos.write(buf, 0, len);              }                // 给客户端一个回馈信息              BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));              out.write("上传成功!"); // 写完需要刷新一下,或者关闭流                // 关闭资源              out.close();              fos.close();              s.close();            } catch (Exception e) {            }        }    }

结果演示

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述