`
javasogo
  • 浏览: 1777742 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

java p2p多文件传输程序的实现

阅读更多
java p2p多文件传输程序的实现,主要利用了java中的socket,SocketThread类,下面是实现过程,Server.java类,//psp文件传输服务,SocketThread.java//文件传输线程类,Application1.java import java.net.*; import java.util.List; public class Server extends Thread { public Server() { try { jbInit(); } catch (Exception ex) { ex.printStackTrace(); } }
<!--\\end Abstract\\-->

源码中得类有:

Application1.java//程序启动类

MainFrame.java//文件传输程序的主界面类

Server.java//传输程序的服务类,主要实现p2p文件传输

SettingDialog.java//传输文件设置类,比如端口,线程数

SocketThread.java//线程类

TransFileDialog.java//选择传输文件对话框

TransFileManager.java//

TransFilePanel.java//panel

SocketThread.java类代码

package trans;

import java.net.Socket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.*;
import java.net.*;

/**
* Socket线程
*/
public class SocketThread extends Thread {
public SocketThread() {
try {
jbInit();
} catch (Exception ex) {
ex.printStackTrace();
}
}

public final static int CACHE_SIZE = 10240; //缓存大小

public final static int FILE_TRANS_STATUS_FILENAME = 0x01; //文件名传输状态

public final static int FILE_TRANS_STATUS_CONTEXT = 0x02; //文件内容传输状态

public final static int FILE_TRANS_STATUS_WAITFORCONFIRM = 0x03; //等待确认接收文件

public final static int FILE_TRANS_STATUS_SUCCESS = 0x04; //文件传输成功

public final static int FILE_TRANS_STATUS_FAIL = 0x05; //文件传输失败

public final static int FILE_TRANS_STATUS_CANCELTRANS = 0x06; //取消文件传输

public final static int PACKAGE_TYPE_FILENAME = 0x01; //文件名包

public final static int PACKAGE_TYPE_CONTEXT = 0x02; //文件内容包

public final static int PACKAGE_TYPE_CONFIRMRECEIVE = 0x03; //是否接收文件

private Socket aSocket; //套接字

private String serverName; //服务器名称

private DataInputStream dis; //输入流

private DataOutputStream dos; //输出流

private DataInputStream fDis; //文件输入流

private RandomAccessFile raf; //文件输出流

private boolean fileSender = false; //文件发送者

private boolean running = false; //线程运行

public int fileTransStatus = 0x0; //文件传输状态

private File aFile; //传输的文件

public long fileSize; //文件大小

private String fileName; //文件名称

private String errorMessage; //错误消息

private long transFileLength = 0; //已传输字节数

private byte [] dataBuf;

private String message; //验证消息

private String IP; //目标IP

private int port; //目标端口

private boolean fileTransed=false; //文件是否已经开始传输

int count=0;

//接收者构造函数
public SocketThread(Socket aSocket) {
this.aSocket = aSocket;
try {
aSocket.setSoTimeout(300000);
} catch (SocketException ex) {
}
byte[] address = aSocket.getInetAddress().getAddress();
IP = (address[0] & 0xff) + "." + (address[1] & 0xff) + "." +
(address[2] & 0xff) + "." + (address[3] & 0xff);
try {
dis = new DataInputStream(aSocket.getInputStream());
dos = new DataOutputStream(aSocket.getOutputStream());
fileTransStatus = FILE_TRANS_STATUS_FILENAME;
} catch (IOException ex) {
setError("创建连接错误!");
}

try {
aSocket.setReceiveBufferSize(CACHE_SIZE*2);
} catch (SocketException ex1) {
ex1.printStackTrace();
}
dataBuf=new byte[CACHE_SIZE+100];
}

//发送者构造函数
public SocketThread(String serverName, int portNo, String fileName,
String message) {
aFile = new File(fileName);
this.fileName = aFile.getName();
this.fileSize = fileSize;
fileSender = true;
if (message != null) {
this.message = message;
}
this.IP = serverName;
this.port = portNo;
dataBuf=new byte[CACHE_SIZE];
}

//线程执行函数
public void run() {
running = true;
if (fileSender) {
try {
aSocket = new Socket(IP, port);
aSocket.setSoTimeout(300000);
aSocket.setSendBufferSize(CACHE_SIZE*2);
dos = new DataOutputStream(aSocket.getOutputStream());
dis = new DataInputStream(aSocket.getInputStream());
fDis = new DataInputStream(new FileInputStream(aFile));
fileTransStatus = FILE_TRANS_STATUS_FILENAME;
} catch (UnknownHostException ex1) {
ex1.printStackTrace();
setError("连接服务器错误!");
} catch (IOException ex1) {
ex1.printStackTrace();
setError("创建连接错误!");
}

} while (running) {
if (fileSender) {
sendFile();
} else {
receiveFile();
}
try {
Thread.sleep(6);
} catch (InterruptedException ex) {
}
}
}

//从socket读
private int readFromSocket(byte[] data) throws IOException {
int length = 0;
length = fDis.read(data);
return length;
}

//从socket读
private int readFromSocket() throws IOException {
int buf = 0;
buf = dis.readInt();
return buf;
}

//从文件读
private int readFromFile(byte[] data,int off,int length) {
int len=0;
try {
len = fDis.read(data,off,length);
} catch (IOException ex) {
setError("文件读取错误!");
}
return len;
}

//写入socket
private void writeToSocket(byte[] data) throws IOException {
dos.write(data);
}

//写入文件
private void writeToFile(byte[] data,int off,int length) throws IOException {
raf.write(data,off,length);
}

//写入socket
private void writeToSocket(int data) throws IOException {
dos.writeInt(data);
}

private void writeToSocket(long data) throws IOException {
dos.writeLong(data);
}

private long readLongFromSocket() throws IOException {
return dis.readLong();
}

//打包
private byte[] doPackage(byte[] data, int length) throws IOException {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream bufDos = new DataOutputStream(buf);
DataOutputStream baosDos = new DataOutputStream(baos);
switch (fileTransStatus) {
case FILE_TRANS_STATUS_FILENAME: {
bufDos.writeInt(PACKAGE_TYPE_FILENAME);
bufDos.writeInt(fileName.getBytes().length);
bufDos.write(fileName.getBytes());
bufDos.writeLong(fileSize);
if (message!=null) {
bufDos.writeInt(message.getBytes().length);
bufDos.write(message.getBytes());
} else {
bufDos.writeInt(-1);
}
baosDos.writeInt(buf.toByteArray().length);
baosDos.write(buf.toByteArray());
break;
}
case FILE_TRANS_STATUS_CONTEXT: {
bufDos.writeInt(PACKAGE_TYPE_CONTEXT);
if ((transFileLength + length) >= fileSize) {
bufDos.writeInt(0);
} else {
bufDos.writeInt(1);
}
bufDos.writeInt(length);
bufDos.write(data, 0, length);
baosDos.writeInt(buf.toByteArray().length);
baosDos.write(buf.toByteArray());
break;
}
}
return baos.toByteArray();
}

//停止线程
public void stopThread() {
running = false;
try {
if (dis != null) {
dis.close();
}
if (dos != null) {
dos.close();
}
if (fDis != null) {
fDis.close();
}
if (raf != null) {
raf.close();
}
} catch (Exception ex) {
}
}

//解包
private void upPackage(byte[] data) {
ByteArrayInputStream bias = new ByteArrayInputStream(data);
DataInputStream biasDis = new DataInputStream(bias);
int type = 0;
try {
type = biasDis.readInt();
} catch (SocketTimeoutException ex) {
setError("网络超时!");
} catch (IOException ex1) {
setError("对方取消了文件传输或网络错误!");
}
switch (type) {
case PACKAGE_TYPE_FILENAME: {
try {
int length = biasDis.readInt();
bias.read(dataBuf,0,length);
fileName = new String(dataBuf,0,length);
fileSize = biasDis.readLong();
length = biasDis.readInt();
if (length !=-1) {
bias.read(dataBuf,0,length);
message = new String(dataBuf,0,length);
}
fileTransStatus = FILE_TRANS_STATUS_WAITFORCONFIRM;
} catch (SocketTimeoutException ex) {
setError("网络超时!");
} catch (IOException ex) {
setError("对方取消了文件传输或网络错误!");
}
break ;
}
case PACKAGE_TYPE_CONTEXT: {
try {
int flag = biasDis.readInt();
int length = biasDis.readInt();
bias.read(dataBuf,0,length);
writeToFile(dataBuf,0,length);
transFileLength += length;
if (flag == 0) {
fileTransStatus = FILE_TRANS_STATUS_SUCCESS;
stopThread();
}
} catch (SocketTimeoutException ex) {
setError("网络超时!");
} catch (IOException ex) {
setError("对方取消了文件传输或网络错误!");
}
break ;
}
}
}

//发送文件
private void sendFile() {
int length;
switch (fileTransStatus) {
case FILE_TRANS_STATUS_FILENAME: {
try {
byte [] buf;
fileName = aFile.getName();
fileSize = aFile.length();
buf = doPackage(null, 0);
writeToSocket(buf);
fileTransStatus = FILE_TRANS_STATUS_WAITFORCONFIRM;
} catch (IOException ex) {
setError("对方取消了文件传输或网络错误!");
}
break ;
}
case FILE_TRANS_STATUS_WAITFORCONFIRM: {
int flag;
try {
flag = readFromSocket();
if (flag == 0) {
setError("对方拒绝了文件传输!");
} else {
fileTransStatus = FILE_TRANS_STATUS_CONTEXT;
transFileLength = readLongFromSocket();
fDis.skip(transFileLength);
aSocket.setSoTimeout(30000);
}
} catch (SocketTimeoutException ex) {
setError("网络超时!");
} catch (IOException ex) {
setError("对方取消了文件传输或网络错误!");
}
break ;
}
case FILE_TRANS_STATUS_CONTEXT: {
length = readFromFile(dataBuf,0,CACHE_SIZE);
try {
writeToSocket(doPackage(dataBuf, length));
transFileLength += length;
if (transFileLength >= fileSize) {
fileTransStatus = FILE_TRANS_STATUS_SUCCESS;
Thread.sleep(1000);
stopThread();
}
} catch (IOException ex) {
setError("对方取消了文件传输或网络错误!");
} catch (InterruptedException ex1) {

}
count++;
if(count==2){
//stopThread();
}
break ;
}
}
}

//接收文件
private void receiveFile() {
if (fileTransStatus == FILE_TRANS_STATUS_CONTEXT ||
fileTransStatus == FILE_TRANS_STATUS_FILENAME) {
try {
int length = dis.readInt();
int len=dis.read(dataBuf,0,length);
while(len<length){
len=len+dis.read(dataBuf,len,length-len);
}
upPackage(dataBuf);
} catch (SocketTimeoutException ex) {
setError("网络超时!");
ex.printStackTrace();
} catch (IOException ex) {
setError("对方取消了文件传输或网络错误!");
}
} else if (fileTransStatus == FILE_TRANS_STATUS_CANCELTRANS) {
try {
doPackage(null, 0);
} catch (IOException ex1) {
}
setError("已取消文件传输!");
}
}

//确认是否接收文件
public void confirmReceiveFile(boolean flag, String fileName, long off) {
if (flag) {
try {

writeToSocket(1);
if (off >0) {
writeToSocket(off);
} else {
writeToSocket(0L);
File aFile=new File(fileName);
if(aFile.exists()){
System.out.println("*");
aFile.delete();
}
}
raf = new RandomAccessFile(fileName, "rws");
this.fileName = fileName;
fileTransStatus = FILE_TRANS_STATUS_CONTEXT;
fileTransed=true;
raf.seek(off);
} catch (FileNotFoundException ex) {
setError("创建文件错误!");
} catch (IOException ex) {
setError("对方取消了文件传输或网络错误!");
}
transFileLength = off;
} else {
try {
writeToSocket(0);
writeToSocket(0L);
} catch (IOException ex) {
setError("对方取消了文件传输或网络错误!");
}
}
}


//返回已传输字节数
public long getTransFileLength() {
return transFileLength;
}

//设置错误消息
public void setError(String errorMessage) {
fileTransStatus = FILE_TRANS_STATUS_FAIL;
this.errorMessage = errorMessage;
if (!fileSender&&fileTransed) {
File tmpFile = new File(fileName + ".tmp");
try {
DataOutputStream dos = new DataOutputStream(new
FileOutputStream(
tmpFile));
dos.writeLong(transFileLength);
dos.writeLong(fileSize);
dos.close();
} catch (IOException ex) {
}
}
stopThread();
}


//返回错误消息
public String getErrorMessage() {
return errorMessage;
}

//返回传输状态
public int getStatus() {
return fileTransStatus;
}

//是否是文件发送者
public boolean isFileSender() {
return fileSender;
}

public void cancelTrans() {
if (fileTransStatus == FILE_TRANS_STATUS_WAITFORCONFIRM) {
confirmReceiveFile(false, null, 0);
}
setError("已取消文件传输!");
}

public String getMessage() {
return message;
}

public String getIP() {
return IP;
}

public int getPort() {
return port;
}

public String getFileName() {
if (fileName.length() > 10) {
return fileName.substring(0, 10) + "..." +
fileName.substring(fileName.lastIndexOf('.'),
fileName.length());
} else {
return fileName;
}
}

public String getFileTransMessage(){
if(fileSender){
return "文件发送 目标IP: "+getIP()+" 端口:"+getPort();
}
else{
return "文件接收 来自: "+getIP();
}
}

private void jbInit() throws Exception {
}
}
由于文件太多,无法一一简绍,如果需要进一步了解p2p文件传输你可以下载改源码,下载地址:

http://www.ie1.cn/Code-Source/Java_Code/bttxt-207.html

分享到:
评论

相关推荐

    java文件p2p传输

    java模仿电驴、迅雷实现多线程文件传输,可用于局域网或internet文件传输发送,程序采用套接字实现p2p(即点到点)文件传输。

    java语言通过Socket实现文件传输

    在Unix/Linux/Windows环境下,通过Socket方式实现一个基于Client/Server或P2P模式的文件传输程序。

    java文件p2p传输_java_

    基于JAVA的P2P协议的仿真代码程序,可以在IDEA和eclipse等平台上运行

    C++_p2p实现多线程文件传输

    笔者一直想寻求一种简 单有效,且具备多线程断点续传的方法来实现点与点之间的文件传送问题,经过大量的翻阅资料与测试,终于实现了,现把它共享出来,与大家分享。 我写了一个以此为基础的实用程序(网络传圣,包含...

    JAVA文件传输P2P源码

    由于学习环境下``在同一个局域网内``没有和朋友之间传输文件的工具...很麻烦``于是写了这个小程序``希望对您有用`````

    p2p.zip_P2P_p2p文件分发系统_文件传输

    基于java的p2p文件传输,分别实现了客户端和服务器端程序

    java 文件传输 源代码和课程设计报告

    任务概述 本项任务要开发一款P2P文件传输软件,该软件可以在局域网和互连上使用,具有文件传输,断点续传,多线程连接等功能。

    java UDP实现的P2P通信(可准确传输文件)

    一个用java实现的UDP通信程序,有详细注释,有测试UI,成功解决了UDP丢包问题。程序正确可运行。

    基于P2P的局域网即时通信系统(Java版)

    一、设计题目:基于P2P的局域网即时通信系统 二、语言环境:Java 三、已知技术参数和设计要求: 1、实现一个图形用户界面局域网内的消息系统。...文件传输进程显示及操作按钮或菜单。 (参考可以,抄袭请自重)

    JAVA的综合加解密聊天程序,附带文档

    利用RSA算法的公私密钥对DES算法的密钥进行加解密,对称DES密钥用来对聊天消息进行加解密,SHA算法用来对传输的数据进行数据校验。Java本版的机遇socket的聊天程序,课程学习资料和作业。附带详细代码说明文档。

    基于JAVA的局域网文件传输及聊天应用

    虽然目前许多桌面应用程序都是都具有文件传输及聊天的应用。但许多都基于C/S模或B/S模式需要服务器,而设计单独的服务器对于例如学生宿舍,家庭等这些场合不是很经济。这对于小型局域网的应用限制很大。本课题所设计...

    Java思维导图xmind文件+导出图片

    分布式架构 漫谈分布式架构 初识分布式架构与意义 如何把应用从单机扩展到分布式 大型分布式架构演进过程 分布式架构设计 主流架构模型-SOA架构和微服务架构 领域驱动设计及业务驱动... 手写实现多协议RPC框架

    java源码包---java 源码 大量 实例

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    JAVA上百实例源码以及开源项目

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    java源码包4

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    java源码包3

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    java源码包2

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    JAVA上百实例源码以及开源项目源代码

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    28个目标文件 内容索引:JAVA源码,媒体网络,飞鸽传书 Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程...

Global site tag (gtag.js) - Google Analytics