案例——TCP上传图片

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) {

		}

	}

}

结果演示

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

posted @ 2019-10-19 15:19  头发是我最后的倔强  阅读(655)  评论(0编辑  收藏  举报