一:客户端
public class TCPClientTU {
public static void main(String[] args) throws IOException {
/** 实现TCP图片上传客户端
* 实现步骤:
* 1. Socket套接字连接服务器
* 2. 通过Socket获取字节输出流,写图片
* 3. 使用自己的流对象,读取图片数据源
* FileInputStream
* 4. 读取图片,使用字节输出流,将图片写到服务器
* 采用字节数组进行缓冲
* 5. 通过Socket套接字获取字节输入流
* 读取服务器发回来的上传成功
* 6. 关闭资源
*/
Socket socket = new Socket("127.0.0.1",8888);
//获取字节输出流,图片写到服务器端
OutputStream outputStream = socket.getOutputStream();
//创建字节输入流,读取本机上的数据源(图片)
FileInputStream fileInputStream = new FileInputStream("E:\\七岁的绝密图片\\" +
"动漫ACG\\颓废.jpg");//路径写自己想上传的图片的路径
//开始写字节数组
int length ;
byte [] bytes = new byte[1024];
while((length=fileInputStream.read(bytes))!=-1){
outputStream.write(bytes, 0, length);
}
//终止
socket.shutdownOutput();
//服务器回应上传成功
InputStream inputStream = socket.getInputStream();
length = inputStream.read(bytes);
System.out.println(new String(bytes,0,length));
fileInputStream.available();
socket.close();
}
}
二:Upload类实现Runnable接口
因为在同一时刻可能不止一个用户上传图片,比如CSDN用户在主页上传自己的头像,就可能存在许多用户同时上传的情况,所有在服务器端加上多线程技术,可以更大程度上模拟当时的情景。还有一个细节,就是图片可能会有重名的情况发生,能、那么将会存在覆盖的情况,所以下面的代码针对这个情况做了处理
public class Upload implements Runnable{
private Socket socket;
public Upload(Socket socket){
this.socket = socket;
}
public void run() {
try{
InputStream inputStream = socket.getInputStream();
//将目的文件夹封装到File对象
File Picture = new File("C:\\Users\\18309\\Desktop\\Picture");
if(!Picture.exists()){
Picture.mkdir();
}
//防止文件因为重名而被覆盖,重新定义文件名
//规则:域名+毫秒值+6位随机数
String filename = "nyist"+System.currentTimeMillis()
+new Random().nextInt(999999)+".jpg";
//创建字节输入流,将图片写进Picture文件夹中
FileOutputStream fileOutputStream= new FileOutputStream(Picture+
File.separator+filename);
byte [] bytes = new byte[1024];
int length;
while((length = inputStream.read(bytes))!=-1){
fileOutputStream.write(bytes, 0,length);
}
socket.getOutputStream().write("上传成功".getBytes());
fileOutputStream.close();
socket.close();
}catch (Exception ex){
System.out.println(ex);
}
}
}
三:服务器端
//服务器永不停歇
public class TCPThreadServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
//获取一个客户端就必须要开启一个新的线程
while(true) {
Socket socket = serverSocket.accept();
new Thread(new Upload(socket)).start();//传递的是接口的实现类
}//出现一个客户端就要开一个线程
}
}
运行情况与结果展示: