JAVA 基于TCP协议的一对一,一对多文件传输实现

最近老师给我们上了多线程和TCP和UDP协议,其中一个要求就是我们用JAVA协议一个基于TCP和UDP这两种协议的一对一文件上传和一对多文件上传。

然后我就开始分析TCP和UDP这两个协议的特点,发现TCP是流传输,抓住这一点就好实现了。

现在我们需要解决一下几个问题,

1.如何确定文件名称

2.如何完成数据传输,并复原成原来的文件。

解决方案就是,对象这是个好东西,因为TCP支持流传输的缘故,我们把每个文件对象化,这样我们就很容易实现基于TCP的多文件上传了。

下面是文件对象代码:

因为我考虑到了以后移植到web端也可以用,所以我添加了源地址这一栏。

packagecom.org.gjt.WebSocket.work1.entity;

importjava.io.Serializable;

/**

* @author gjt

* @version 1.0

* @Title: 文件实体类

* @date 2018/5/24/10:45

*/

publicclassFileSettingimplementsSerializable{

privatestaticfinallongserialVersionUID = 613659699548582156L;

/**

* 文件名称

*/

privateString fileName;

/**

* 文件类型

*/

privateString fileType;

/**

* 文件大小

*/

privatelongsize;

/**

* 文件内容

*/

privateString stream;

/**

* 文件源地址

*/

privateString originPath;

publicString getOriginPath() {

returnoriginPath;

}

publicvoidsetOriginPath(String originPath) {

this.originPath = originPath;

}

publicString getFileName() {

returnfileName;

}

publicvoidsetFileName(String fileName) {

this.fileName = fileName;

}

publicString getFileType() {

returnfileType;

}

publicvoidsetFileType(String fileType) {

this.fileType = fileType;

}

publiclonggetSize() {

returnsize;

}

publicvoidsetSize(longsize) {

this.size = size;

}

publicString getStream() {

returnstream;

}

publicvoidsetStream(String stream) {

this.stream = stream;

}

}

其中需要注意的就是,我们需要对文件对象进行序列化。这是一种处理对象流的机制。原理的话网上很多。

下面是TCP的配置实体类

packagecom.org.gjt.WebSocket.work1.entity;

/**

* @author gjt

* @version 1.0

* @Title: tcp连接实体

* @date 2018/5/24/9:52

*/

publicclassTCPsetting {

/**

* 设置上传服务器

*/

publicfinalstaticString conAddr ="127.0.0.1";

/**

* 设置要上传的端口

*/

publicfinalstaticintport =8888;

}

到时候如果要放在服务器上只需要修改conAddr既可。

下面是TCPSocket端的代码

单独剥离出来的原因,主要是我希望能尽可能不让开发人员介入底层配置只需要填空即可。后面我还会对这个再一次封装。

packagecom.org.gjt.WebSocket.work1;

importcom.org.gjt.WebSocket.work1.entity.TCPsetting;

importjava.io.IOException;

importjava.net.Socket;

/**

* @author gjt

* @version 1.0

* @Title: tcpSocketClient

* @date 2018/5/24/11:10

*/

publicclassTcpSocketClient {

/**

* 建立socket连接

* @return

*/

publicSocket ConnectTcpClient(){

Socket clientSocket =null;

/**

* 建立socket连接

*/

try{

clientSocket =newSocket(TCPsetting.conAddr,TCPsetting.port);

}catch(Exception e) {

e.printStackTrace();

}

returnclientSocket;

}

/**

* 关闭连接

* @param socket

*/

publicvoidClose(Socket socket){

try{

socket.close();

System.out.println("关闭成功!");

}catch(IOException e) {

e.printStackTrace();

}

}

}

下面是TCP协议的Client端

packagecom.org.gjt.WebSocket.work1;

importcom.org.gjt.WebSocket.utils.FileUtils;

importcom.org.gjt.WebSocket.work1.entity.FileSetting;

importjava.io.*;

importjava.net.Socket;

importjava.util.Scanner;

/**

* @author gjt

* @version 1.0

* @Title: tcp一对一文件上传:客户端

* @date 2018/5/24/9:50

*/

publicclassTCPSingleClient {

/**

* 建立客户端socket连接

*/

privatestaticTcpSocketClient conn =newTcpSocketClient();

/**

* 设置文件信息

*/

privatestaticFileSetting file =newFileSetting();

/**

* 启动文件工具类

*/

privatestaticFileUtils fileUtils =newFileUtils();

/**

* 发送文件

* @param path

* @throws Exception

*/

privatestaticvoidSendFile(String path)throwsException {

Socket connect = conn.ConnectTcpClient();

OutputStream os = connect.getOutputStream();

ObjectOutputStream oos =newObjectOutputStream(os);

oos.writeObject(file);

oos.writeObject(null);

oos.flush();

connect.shutdownOutput();

String infoString=null;

InputStream is = connect.getInputStream();

BufferedReader br=newBufferedReader(newInputStreamReader(is));

String info=null;

while((info=br.readLine())!=null){

System.out.println("服务器端的信息:"+ info);

}

Scanner sc =newScanner(System.in);

sc.nextInt();

connect.shutdownInput();

oos.close();

os.close();

is.close();

br.close();

conn.Close(connect);

}

/**

* 初始化文件并组装

* @param path

*/

privatestaticvoidinitFiles(String path) {

File selectFile =newFile(path);

String name = selectFile.getName();

String fileOriginPath = selectFile.getPath();

String type = name.substring(name.lastIndexOf(".") +1);

String content = fileUtils.encryptToBase64(path);

longsize = selectFile.length();

System.out.println("***************文件基本信息***************");

System.out.println("name:"+name);

System.out.println("fileOriginPath:"+fileOriginPath);

System.out.println("type:"+type);

System.out.println("content:"+content);

System.out.println("size:"+size);

System.out.println("***************文件基本信息***************");

file.setFileName(name);

file.setSize(size);

file.setStream(content);

file.setFileType(type);

file.setOriginPath(fileOriginPath);

}

publicstaticvoidmain(String[] args) {

String path ="E:\\webstromProject\\eduProject\\classWork\\test.jpg";

initFiles(path);

try{

SendFile(path);

}catch(Exception e) {

e.printStackTrace();

}

}

}

TCPserver端

packagecom.org.gjt.WebSocket.work1;

importcom.org.gjt.WebSocket.utils.FileUtils;

importcom.org.gjt.WebSocket.work1.entity.FileSetting;

importcom.org.gjt.WebSocket.work1.entity.TCPsetting;

importjava.io.*;

importjava.net.ServerSocket;

importjava.net.Socket;

/**

* @author gjt

* @version 1.0

* @Title: 一对一上次:服务端

* @date 2018/5/24/16:55

*/

publicclassTCPSingleServer {

/**

* 启动文件工具类

*/

privatestaticFileUtils fileUtils =newFileUtils();

/**

* 接受传输过来的对象

*/

privatestaticFileSetting fileSetting =newFileSetting();

privatestaticvoidStartService()throwsException {

Object obj =null;

ServerSocket serverSocket =newServerSocket(TCPsetting.port);

System.out.println("服务器启动,等待客户端的连接。。。");

Socket socket = serverSocket.accept();

OutputStream os =null;

PrintWriter pw =null;

InputStream is = socket.getInputStream();

ObjectInputStream ois=newObjectInputStream(is);

obj = ois.readObject();

if(obj !=null){

System.out.println("接收到来自["+socket.getInetAddress().getHostAddress()+"]的文件");

fileSetting = (FileSetting) obj;

/**

* 开始存储工作

*/

File dir =newFile("E:\\"+socket.getInetAddress().getHostAddress());

if(!dir.exists()){

dir.mkdir();

}

File file =newFile(dir, socket.getInetAddress().getHostAddress()+fileSetting.getFileName());

/**

* 获取base64流转为指定文件

*/

String stream = fileSetting.getStream();

fileUtils.decryptByBase64(stream,file.getPath());

System.out.println("保存成功");

}

os=socket.getOutputStream();

pw=newPrintWriter(os);

pw.println("传输完成!");

pw.flush();

socket.shutdownOutput();

if(pw!=null){

pw.close();

}

if(os!=null){

os.close();

}

if(socket!=null){

socket.close();

}

}

publicstaticvoidmain(String[] args) {

try{

StartService();

}catch(Exception e) {

e.printStackTrace();

}

}

}

这是基本代码,实现基于TCP的文件上传。

修改成一对多也很简单,之后我会把两个版本的代码上传到我的github上去,有想法的大佬可以下载下来试试。

关于修改成多文件上传,只需要在原来传输对象基础上修改成对象列表即可。

代码链接:https://github.com/1163236754/JAVA-Code/tree/master/WebSocket/work1

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180525G0YA7E00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券