一、上传文件(UpLoadFile)
(1)、题目
1.编写一个服务端和一个客户端
2.服务器端在8888端口监听
3.客户端连接服务端,发送一张照片到d:\\java\\风景图.jpg
4.服务器端接收到客户端发送的图片,保存到src下,发送“收到图片”再退出
5.客户端就收服务端发送的“收到图片”,再退出
6.该程序要求使用StreamUtil.java(已经写好,直接使用)
(2)、思路分析
1.将磁盘上的图片(二进制文件)输入到客户端,存储为文件字节数组
2.将客户端的文件字节数组输出到数据通道
3.到文件数据从数据通道输入到服务端,存储为文件字节数组
4.将程序端的文件字节数组输出为d盘下的图片
5.服务端输出“收到图片”到数据通道
6.客户端从数据通道输入“收到图片”
程序结束
(3)代码示范
==============服务端================
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPFileUploadServer {
public static void main(String[] args) throws Exception {
//创建端口,本机服务端监听6666端口
ServerSocket serverSocket = new ServerSocket(6666);
System.out.println("服务端等待连接");
//等待端口连接
Socket socket = serverSocket.accept();
//从数据通道读取数据
//通过socket得到输入流
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
byte[] bytes = StreamUtils.streamToByteArray(bis);
//将得到的bytes数组,写入到指定的路径,得到一个文件
String destFilePath="d:\\风景图.JPG";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
bos.write(bytes);
//向客户端回复收到图片
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("收到图片");
writer.flush();//把内容刷新到数据通道
socket.shutdownOutput();//设置结束标记
//关闭流
bos.close();
bis.close();
socket.close();
serverSocket.close();
}
}
===============客户端=================
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
@SuppressWarnings({"all"})
public class TCPFileUploadClient {
public static void main(String[] args) throws Exception {
//传入本机地址和端口
Socket socket = new Socket(InetAddress.getLocalHost(),6666);
String file="d:\\java\\风景图.JPG";
//先将图片存入到字节数组中,此时图片是文件,字节数组是程序,从图片到数组是输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
byte[] bytes = StreamUtils.streamToByteArray(bis);
//将文件的字节数组传送到运输通道
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write(bytes);
//设置写入数据的结束标志
socket.shutdownOutput();
//接受从服务端回复的消息,
//因为服务端传入到数据通道的数据的结束标志没有使用writer.newLine()的换行符
//在客户端接受数据时,可以既可以使用字节流,也可以使用字符流
InputStream inputStream = socket.getInputStream();
//使用StreamUtils的方法,直接将inputstream读取到的内容转成字符串
String s = StreamUtils.streamToString(inputStream);
System.out.println(s);
//关闭相关的流
inputStream.close();
bos.close();
bis.close();
socket.close();
}
}
===============StreamUtils类和方法===============
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 此类用于演示关于流的读写方法
*
*/
public class StreamUtils {
/**
* 功能:将输入流转换成byte[], 即可以把文件的内容读入到byte[]
* @param is
* @return
* @throws Exception
*/
public static byte[] streamToByteArray(InputStream is) throws Exception{
ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象
byte[] b = new byte[1024];//字节数组
int len;
while((len=is.read(b))!=-1){//循环读取
bos.write(b, 0, len);//把读取到的数据,写入bos
}
byte[] array = bos.toByteArray();//然后将bos 转成字节数组
bos.close();
return array;
}
/**
* 功能:将InputStream转换成String
* @param is
* @return
* @throws Exception
*/
public static String streamToString(InputStream is) throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder= new StringBuilder();
String line;
while((line=reader.readLine())!=null){
builder.append(line+"\r\n");
}
return builder.toString();
}
}
二、下载文件
(1)、题目
1.编写客户端程序和服务端程序
2.客户端可以输入一个音乐文件名,比如高山流水,服务端收到音乐名后,可以给客户端返回之歌音乐文件,如果服务器没有这个文件,返回一个默认的文件
3.客户端收到文件后,保存在本地
4.使用Stream.utils类
(2)、思路分析
1.客户端输出要下载的文件名到数据通道
2.服务端从数据通道输入文件名
3.将某个目录要下载的文件生成字节数组
4.如果要下载的文件名和目录下的文件名一致,服务端就输出该文件的字节数组到数据通道,如果不一致,就输出默认文件
5.客户端从数据通道输入文件的字节数组
6.客户端将文件数组存储到指定文件中
====================服务端============================
import com.hspedu.upload.StreamUtils;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPFileDownloadServer {
public static void main(String[] args) throws Exception {
//1.监听9999端口
ServerSocket serverSocket = new ServerSocket(9999);
//2.等待客户端连接
Socket socket= serverSocket.accept();
System.out.println("服务端在9999端口监听,等待客户端连接");
//3.读取客户端发送的要下载的文件名
//担心客户端发送过来的文件名过长,所以使用while循环读取
InputStream inputStream = socket.getInputStream();
byte[]b=new byte[1024];
int len=0;
String downLoadFileName="";
while((len=inputStream.read(b))!=-1){
downLoadFileName+=new String(b,0,len);
}
System.out.println("客户端希望下载的文件名="+downLoadFileName);
//服务器上有两个文件,无名.mp3和高山流水.mp3
//如果客户下载的是高山流水就返回该文件,如果不是就返回无名.mp3
String resFileName="";
if("高山流水".equals(downLoadFileName)){
resFileName="src\\高山流水.mp3";
}else{
resFileName="src\\无名.mp3";
}
//4.创建一个输入流,读取文件
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream(resFileName));
//5.使用工具类StreamUtils,读取文件到一个字节数组
byte[] bytes = StreamUtils.streamToByteArray(bis);
//得到socket关联的输出流
BufferedOutputStream bos =
new BufferedOutputStream(socket.getOutputStream());
//7.写入到数据通道,返回给客户端
bos.write(bytes);
//设置结束标志
socket.shutdownOutput();
//8.关闭资源
bos.close();
bis.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
==========================客户端=========================
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
//文件下载的客户端
public class TCPDownloadClient {
public static void main(String[] args) throws Exception {
//1.接受用户输入,指定下载文件名
Scanner scanner = new Scanner(System.in);
System.out.println("请输入下载的文件名");
String downloadFileName=scanner.next();
//客户端连接服务端,准备发送
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
//3.获取和Socket相关联的输出流
OutputStream outputStream = socket.getOutputStream();
outputStream.write(downloadFileName.getBytes());
//设置写入结束标志
socket.shutdownOutput();
//读取服务端返回的文件(字节数组)
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
byte[]bytes=StreamUtils.streamToByteArray(bis);
//5.得到一个输出流,准备将bytes写入到磁盘文件
String filePath="d:\\java\\"+downloadFileName+".mp3";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
bos.write(bytes);
//6.关闭相关资源
bos.close();
bis.close();
outputStream.close();
socket.close();
System.out.println("客户端下载完毕,正确退出");
}
}
=================StreamUtils类和使用到的方法======================
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 此类用于演示关于流的读写方法
*
*/
public class StreamUtils {
/**
* 功能:将输入流转换成byte[], 即可以把文件的内容读入到byte[]
* @param is
* @return
* @throws Exception
*/
public static byte[] streamToByteArray(InputStream is) throws Exception{
ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象
byte[] b = new byte[1024];//字节数组
int len;
while((len=is.read(b))!=-1){//循环读取
bos.write(b, 0, len);//把读取到的数据,写入bos
}
byte[] array = bos.toByteArray();//然后将bos 转成字节数组
bos.close();
return array;
}
/**
* 功能:将InputStream转换成String
* @param is
* @return
* @throws Exception
*/
public static String streamToString(InputStream is) throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder= new StringBuilder();
String line;
while((line=reader.readLine())!=null){
builder.append(line+"\r\n");
}
return builder.toString();
}
}
以上代码思路来源于B站韩顺平零基础30天学会java