客户端的需求分析:
文件上传案例的客户端:读取本地文件,上传到服务器,读取服务器回写的数据明确
数据源:c:\\1.jpg
目的地:服务器
实现步骤:
1.创建一个本地字节输入流 Fileinputstream对象,构造方法中绑定要读取的据源
2.创建一个窨户端 Socket对象,构造方法中绑定服务器的rP地址和端口号
3.使用 Socket中的方法 getoutputstream,获取网络字节输出流 outputstream对象
4.使用本地字节输入流 FileInputstream对象中的方法read读取本地文件
5.使用网客字节输出流 Outputstream对象中的方法 write把读职到的文件上传到服务器
6.使用socket中的法 getInputstream,获取网络字节输入流getInputStream对象
7.使用网络字节输入流 Inputstream对象中的方法read读取服务回写的数据
8.释放资源(FileInputstream,Socket)
客户端的代码实现:
public class TCPClient {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\1.jpg");
Socket socket = new Socket("127.0.0.1",8888);
OutputStream os = socket.getOutputStream();
int len =0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes))!=-1){
os.write(bytes,0,len);
}
//做一个结束标记,让服务器直到文件上传完成
socket.shutdownOutput();
InputStream is = socket.getInputStream();
while ((len = is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
fis.close();
socket.close();
}
}
服务器端的需求分析:
文件上传案例服务器端:读取客户端上传的文件,保存到服务器的硬盘,给客户端回写“上传成功” 明确 数据源:客户端上传的文件 目的地:服务器的硬盘d:\\ upload\\1.jpg 实现步骤 1.创建一个服务器 Serversocket对象,和系统要指定的端口 2使用 ServerSocket对象中的方法 accept,获取到请求的客户端 Socket对象 3.使用 Socket对象中的方法 getInputstream获取到网络字节输入流 Inputstream对象 4.判断d:\\upLoad文件夹是否存在,不存在则创建 5.创建一个本地字节输岀流 FileOutputStreαm对象,构造方法中绑定要输岀的目的地 6.使用网络字节输入流 InputStream对象中的方法read,读取客户端上传的文件 7.使用本地字节输岀流FileOutputStrεαm对象中的方法write,把读取到的文件保存到服务器的硬盘上 8.使用 Socket对象中的方法 getoutputstream,获取到网络字节输出流 outputstream对象 9.使用网络字节输出流 Outputstream对象中的方法wie,给客户端回写“上传成功” 10.释放资源(FileOutputStream,Socket,ServerSocket)
服务器端的代码实现:
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept();
InputStream is = socket.getInputStream();
File file = new File("D:\\UpLoad");
if (!file.exists()){
file.mkdir();
}
FileOutputStream fos = new FileOutputStream(file+"\\1.jpg");
int len =0;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes))!=-1){
fos.write(bytes,0,len);
}
OutputStream os = socket.getOutputStream();
os.write("上传成功".getBytes());
fos.close();
socket.close();
os.close();
is.close();
}
}
为了方式文件名字重复,需要自己制定命名规则来防止因为文件名重复导致的文件覆盖。
由于服务器访问人数比较多,所以考虑使用多线程完成。优化后的代码如下:
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8888);
//为了提高效率,可以使用多线程技术对程序进行修改(使用线程池)
ExecutorService es = Executors.newFixedThreadPool(5);
//该服务器经过一次上传后程序就会终止。所以要让这个服务器一直运行
//即让accept一直处于监听状态
while(true){
Socket socket = server.accept();
es.submit(new Runnable() {
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
File file = new File("D:\\UpLoad");
if (!file.exists()) {
file.mkdir();
}
/*
添加文件命名规则:域名+毫秒值+6位随机数+.jpg
*/
String Filename = "\\HIU" + System.currentTimeMillis() + new Random().nextInt(999999) + ".jpg";
FileOutputStream fos = new FileOutputStream(file + Filename);
int len = 0;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
OutputStream os = socket.getOutputStream();
os.write("上传成功".getBytes());
fos.close();
socket.close();
os.close();
is.close();
}catch (IOException e){
e.printStackTrace();
}
}
});
}
//因此服务器不需要关闭
// server.close();
}
}