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

结果演示



最新文章

  1. NPOI操作EXCEL(三)——反射机制进行excel表格数据的解析
  2. 每天一个命令day1【diff 命令】(具体实例看下一节)
  3. Android 自定义ToggleButton+用SharedPreferences保存用户配置
  4. Kent Beck揭秘Facebook开发部署流程
  5. yii2使用Gii生成代码
  6. 宏观CMS-->功能体系结构内容管理系统
  7. ERRO错误解决方案整理
  8. rocketmq番外篇(一):开发命令行
  9. 复活广州.net俱乐部
  10. java代码之美(2)---Java8 Stream
  11. tomcat中显示本地图片①(未解决)
  12. python接口自动化29-requests-html支持JavaScript渲染页面
  13. Python根据路径名称获取文件的名称以及所在的路径
  14. Advanced Find and Replace(文件内容搜索替换工具)v7.8.1简体中文破解版
  15. 20155215 《Java程序设计》实验二( Java面向对象程序设计)实验报告
  16. MySQL Block Nested-Loop Join(BNL)
  17. springMVC中接收请求参数&&数据转发
  18. python 文件路径操作方法(转)
  19. php 转码函数 你还在用iconv吗?-- 解决sqlserver插入中文失败问题
  20. Linux内存cache/buffer剖析

热门文章

  1. Elasticsearch之联想词示例
  2. spring boot日志logback输出
  3. 2019沈阳网络赛B.Dudu's maze
  4. 深入理解Three.js中透视投影照相机PerspectiveCamera
  5. TestNG(十) 依赖测试
  6. JS 防抖和节流
  7. Mysql学习笔记整理之引擎
  8. React-leaflet在ant-design pro中的基本使用
  9. [sonarqube的使用] sonarqube安装
  10. Kafka系列二之部署与使用