最近在一个课程设计,聊天系统,里面有个功能就是传输文件,我开先用的是udp数据报传输文件,但是发现当传输的文件太大的时候丢包,所以后改用java的socket 的tcp连接传输文件,在局域网中传输文件速度还是可以。
下面是部分代码,可能无法单独运行,因为里面涉及到图形界面,牵扯到其他的类,不过稍加改动就可以了,我把源代码上传到csdn上了,下载地址是:http://download.csdn.net/source/1957266,供大家下载学习使用,由于开发时间短,所以开发时客户端和服务器端共用了一些类,其实这应该分开的,呵呵!
本系统可以多客户端和服务器端进行通信,传输文件。界面不太好看,恶哈哈!
下面还是把传输文件的主要两个类的代码贴出来。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import org.loonsoft.utils.FileProgressBar;
import org.loonsoft.utils.FrameUtils;
import org.loonsoft.utils.ParamaterUtils;
import org.loonsoft.utils.SaveFileDialog;
public class ReceiveFileService implements Runnable {
private ExecutorService exec = Executors.newCachedThreadPool();
private ServerSocket serverSocket = null;
private Socket socket = null;
private FrameUtils frame = null;
public ReceiveFileService(FrameUtils frame) {
this.frame = frame;
try {
serverSocket = new ServerSocket(ParamaterUtils.getFilePort());
// serverSocket = new ServerSocket(8881);
System.out.println("文件监听启动.....");
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
socket = serverSocket.accept();
// System.out.println(socket.getPort());
exec.execute(new Handler(socket, frame).run());
// socket.close();
// serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// public static void main(String[] args) {
// new Thread(new ReceiveFileService()).start();
// }
}
class Handler {
private Socket socket = null;
private FrameUtils frame = null;
private FileProgressBar bar = null;
private final JDialog barDialog = new JDialog();
public Handler(Socket socket, FrameUtils frame) {
this.socket = socket;
this.frame = frame;
}
private DataInputStream getDataInputStream() throws IOException {
return new DataInputStream(socket.getInputStream());
}
private DataOutputStream getDataOutputStream() throws IOException {
return new DataOutputStream(socket.getOutputStream());
}
private String selectedPath() {
return new SaveFileDialog().getPath(frame);
}
private void runBar(int maxSize) {
bar = new FileProgressBar();
bar.setSize(maxSize);
barDialog.setLocation(150, 20);
barDialog.setTitle("文件接收进度");
barDialog.setSize(250, 50);
barDialog.add(bar.getBar());
barDialog.setEnabled(false);
barDialog.setVisible(true);
new Thread(bar).start();
}
public Runnable run() {
return new Runnable() {
public void run() {
try {
DataInputStream in = getDataInputStream();
DataOutputStream os = getDataOutputStream();
byte[] data = new byte[1024];
while(in.available()<=0) ;//同步
int len = in.read(data);
String[] str = new String(data, 0, len, "utf-8").split(";");
String path = selectedPath();
if (len != -1)
path += str[0];//str[0]是文件名加类型
System.out.println(path);
os.write("start".getBytes());
os.flush();
File file = new File(path);
DataOutputStream out = new DataOutputStream(
new FileOutputStream(file));
System.out.println("开始接收.....");
int countSize = 0;
runBar(Integer.parseInt(str[1]));// 启动文件接受进度条
while ((len = in.read(data)) != -1) {
out.write(data, 0, len);
countSize += len;
bar.setSendSize(countSize);
}
os.close();
out.flush();
out.close();
in.close();
barDialog.setVisible(false);
barDialog.dispose();// 关闭文件进度显示框
JOptionPane.showMessageDialog(frame, "文件接受完成!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
System.out.println("关闭....");
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
}
}
发送类:
package org.loonsoft.client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import org.loonsoft.utils.ParamaterUtils;
import org.loonsoft.utils.SendFileProgressBar;
public class SendFileService implements Runnable {
private Socket socket = null;
private String path = null;
private SendFileProgressBar bar = null;
public SendFileService(SendFileProgressBar bar)
throws UnknownHostException, IOException {
this.bar = bar;
socket = new Socket(ParamaterUtils.getIp(), ParamaterUtils
.getFilePort());
// socket = new Socket("127.0.0.1", 8881);
}
private DataOutputStream getDataOutputStream() throws IOException {
return new DataOutputStream(socket.getOutputStream());
}
private DataInputStream getDataInputStream() throws IOException {
return new DataInputStream(socket.getInputStream());
}
private String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public void run() {
try {
DataInputStream read = new DataInputStream(new FileInputStream(
new File(getPath())));
bar.setSize(read.available());// 设置文件的总长度
System.out.println(read.available());
DataOutputStream os = getDataOutputStream();
DataInputStream in = getDataInputStream();
String fileName = path.substring(path.lastIndexOf("//") + 1);//获得文件名加类型
System.out.println(fileName);
os.write((fileName + ";" + read.available()).getBytes("utf-8"));//将文件名和文件大小传给接收端
byte[] data = new byte[1024];
int len = in.read(data);
String start = new String(data, 0, len);
int sendCountLen = 0;
if (start.equals("start")) {
new Thread(bar).start();// 启动文件进度条线程
while ((len = read.read(data)) != -1) {
os.write(data, 0, len);
sendCountLen += len;
bar.setSendSize(sendCountLen);
}
os.flush();
os.close();
read.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}