黑马程序员 Java练习-模拟TCP客户端并发上传图片

时间:2021-09-23 00:27:13
----------------------Android培训Java培训、期待与您交流! ----------------------

程序需要打开两个命令窗口,一个用于充当服务器,一个充当客户端

import java.io.*;
import java.net.*;

/*
练习:编写程序模拟TCP客户端并发上传图片,本地计算机充当服务器,并监听10010端口
客户端:主函数传递参数
1、判断传递的参数是否存在,是否是文件,是否是.jpg格式的文件,大小是否在2Mb内
2、创建客户端端点,指定服务器地址和端口号
3、创建输入流,读取要上传的文件
4、创建输出流,将读取到的数据写到Socket输出流,
5、关闭Socket输出流
6、创建输入流读取Socket输入流中的数据,即读取服务器返回的信息
7、关闭客户端端点
*/
class PicClient {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("请选择一个jpg格式的图片");
return;
}
File file = new File(args[0]);
if (!(file.exists() && file.isFile())) {
System.out.println("文件不存在,或不是文件");
return;
}
if (!file.getName().endsWith(".jpg")) {
System.out.println("文件格式错误,请重新输入");
return;
}
if (file.length() >= 1024 * 1024 * 2) {
System.out.println("文件过大");
return;
}
Socket s = null;
try {
s = new Socket("FIRE", 10000);
} catch (Exception e) {
throw new RuntimeException("连接服务器失败!");
}
FileInputStream in = null;
try {
in = new FileInputStream(file);
OutputStream os = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
os.write(buf, 0, len);
}
s.shutdownOutput();
InputStream is = s.getInputStream();
byte[] bufin = new byte[1024];
int num = is.read(bufin);
System.out.println(new String(bufin, 0, num));
} catch (Exception e) {
throw new RuntimeException("上传失败!");
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
System.out.println("输入流关闭失败!");
}
try {
s.close();
} catch (IOException e) {
System.out.println("客户端服务关闭失败!");
}
}
}
}

/*
* 线程类 将接收客户端数据的代码放到run方法中
*/
class PicThread implements Runnable {
private Socket s;

public PicThread(Socket s) {
this.s = s;
}

public void run() {
// 定义计数器,用于区分同ip上传文件
int count = 1;
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + ":has connected");
// 根据IP和计数器创建上传文件的名称
File file = new File(ip + "(" + (count++) + ").jpg");
while (file.exists())
file = new File(ip + "(" + (count++) + ").jpg");
FileOutputStream out = null;
try {
InputStream is = s.getInputStream();
out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while ((len = is.read(buf)) != -1) {
out.write(buf, 0, len);
}
OutputStream os = s.getOutputStream();
os.write("上传成功!".getBytes());
} catch (Exception e) {
throw new RuntimeException("上传失败!");
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
System.out.println("输出流关闭失败!");
}
try {
s.close();
} catch (IOException e) {
System.out.println("客户端服务关闭失败!");
}
}
}
}

/*
* 服务器端:使用多线程实现客户端并发上传 1、创建爱你服务器端端点,并监听指定端口 2、使用while(true)循环连续监听客户端端口
* 3、使用多线程,监听到一个客户端端口就创建一个新的接受客户端上传数据的线程,使得客户端可以并发上传数据
*/
class PicServer {
public static void main(String[] args) {
ServerSocket ss = null;
try {
ss = new ServerSocket(10010);
} catch (Exception e) {
throw new RuntimeException("服务器端服务创建失败!");
}
Socket s = null;
while (true) {
try {
s = ss.accept();
} catch (IOException e) {
throw new RuntimeException("获取客户端失败!");
}
new Thread(new PicThread(s)).start();
}
}
}

----------------------Android培训Java培训、期待与您交流! ----------------------