正在等待解决的问题:
毕设在做一个类似QQ聊天软件的东西,里面加入了文件夹传输的功能,但是遇到一个问题:文件有时候能够传输成功,有时候就不能!下面是我文件传输部分使用的原理
我使用的是Tcp连接,发送方通过一个打开窗口让用户选择要发送的文件,然后将接收者的IP和文件名传递给一个专门用于文件发送的线程sendThreadHandler,在这个线程类中,通过接收到IP建立Tcp连接,然后定义FileInputStream,DataOutputStream还有一个缓存Buffer,FileInputStream将问价内容复制到缓存,然后DataOutputStream从缓存取出发送
接收方:通过监听得到连接后将接受任务交给另一个类中的接收线程去做:在这个线程里面,先打开一个保存对话框,用户选择保存的地址和名字,确定后开始接收,和发送方差不多,也是缓存机制。下面是部分具体代码,请高手指点一下哪有问题,再次说明问题情况,文件有时候能发送成功,有时候失败,好像小文件比较容易失败!
定义按钮监听器(部分):
else if(e.getSource()==sendFile){
JFileChooser fc = new JFileChooser();
int result = fc.showOpenDialog(sendButton);
File file = fc.getSelectedFile();
fc.setMultiSelectionEnabled(false);//设置只能选择一个文件
if(file!=null && result==JFileChooser.APPROVE_OPTION){
String fileName = file.getAbsolutePath(); //文件绝对路径
String ip=socket.getInetAddress().getHostAddress();
fileProgressBar.setVisible(true);
new Thread(new sendThreadHandler(ip,fileName)).start();
}
}
sendThreadHandler线程类:
//文件发送线程
class sendThreadHandler implements Runnable{
String ip;
String fileName;
String filename;
Socket socket;
File file;
FileInputStream fis;
OutputStream netOut;
DataOutputStream doc;
public sendThreadHandler(String ip,String fileName){
this.ip=ip;
this.fileName=fileName;
}
public void run(){
try{
file=new File(fileName);
filename=file.getName();
socket=new Socket(ip,4702);
System.out.println("已建立文件传输连接……");
//准备传数据
fis=new FileInputStream(file);
netOut=socket.getOutputStream();
doc=new DataOutputStream(new BufferedOutputStream(netOut));
doc.writeUTF(myName);
doc.flush();
doc.writeUTF(filename);//发送文件名
doc.flush();
long filelength=file.length();
doc.writeLong(filelength);//发送文件长度
doc.flush();
byte[] buf=new byte[4096];
int num=fis.read(buf);
int passed=0;
while(num!=(-1)) {
passed += num;
doc.write(buf,0,num);
doc.flush();
num=fis.read(buf);
final int x = (int) (100*(passed/(double)filelength));
SwingUtilities.invokeLater(new Runnable(){
public void run(){
fileProgressBar.setValue(x);
fileProgressBar.setString(String.valueOf(x)+"%");
System.out.println("已传输:"+x+"%");
}
});
}
fileProgressBar.setVisible(false);
}catch(Exception ex){
System.out.println("Chat.sendThreadHandler.run()"+ex.getMessage());
}finally{
try{
fis.close();
netOut.close();
doc.close();
socket.close();
}catch(Exception e){}
}
}
}
文件传输监听线程:
class recieveFileThread implements Runnable{
ServerSocket serverSocket;//监听文件传输
Socket fileTransferSocket;
public void run(){
try{
serverSocket=new ServerSocket(4702);
while(true){
fileTransferSocket=serverSocket.accept();
new fileRecieve(fileTransferSocket);
}
}catch(Exception ex){
System.out.println("Chat.recieveFileThread.run()"+ex.getMessage());
}
}
}
fileRecieve类:
public class fileRecieve extends JFrame{
JPanel contentPanel;
JProgressBar fileProgressBar=new JProgressBar(0,100);
JLabel filelabel=new JLabel("正在接收");
public fileRecieve(Socket socket){
init();
new Thread(new fileRecieveHandler(socket)).start();
}
//此构造方法用于测试窗口
public fileRecieve(){
init();
}
public void init(){
this.setVisible(true);
this.setSize(new Dimension(550, 120));
this.setLayout(null);
this.setTitle("文件接收");
contentPanel=(JPanel)this.getContentPane();
filelabel.setFont(new java.awt.Font("宋体", 0, 14));
filelabel.setBounds(new Rectangle(10, 10, 520, 28));
fileProgressBar.setStringPainted(true);
fileProgressBar.setBounds(new Rectangle(10, 43, 520, 20));
contentPanel.add(filelabel, null);
contentPanel.add(fileProgressBar, null);
}
//文件传输处理线程
class fileRecieveHandler implements Runnable{
Socket socket=null;
InputStream netIn=null;
DataInputStream in=null;
RandomAccessFile raf=null;
public fileRecieveHandler(Socket socket){
this.socket=socket;
}
public void run(){
try{
netIn=socket.getInputStream();
in=new DataInputStream(new BufferedInputStream(netIn));
String fileFrom=in.readUTF();//获取发送方姓名
String name=in.readUTF(); //获取文件名字
String str="你确认要接收来自"+fileFrom+"的文件:"+name+" 吗?";//提示消息
//下面产生一个提示窗口并将用户的点击事件传递给参数i,然后对参数i进行判断
int i=JOptionPane.showConfirmDialog(null,str,"文件接收",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
if(i==JOptionPane.YES_OPTION)
{
System.out.println("你选择了接收!");
filelabel.setText("正在接收 "+name+" 请稍候……");
JFileChooser fc=new JFileChooser();
System.out.println("已建立JFileChooser");
//下面产生文件保存窗口,并用result来接受用户点击的按钮参数
int result=fc.showSaveDialog(null);
System.out.println("result="+result);
File file1 = fc.getSelectedFile();
String fileName = file1.getAbsolutePath();//绝对路径
if(file1!=null && result==JFileChooser.APPROVE_OPTION){
File file2=new File(fileName);
file2.createNewFile();
raf=new RandomAccessFile(file2,"rw");
long filelength = in.readLong();
System.out.println("要接收的文件长度为"+filelength+"字节");
byte[] buf=new byte[4096];
int num=in.read(buf);
int passed = 0;
while(num!=(-1)){
raf.write(buf,0,num);
raf.skipBytes(num);
passed += num;
num=in.read(buf);
final int x = (int) (100*(passed/(double)filelength));
SwingUtilities.invokeLater(new Runnable(){
public void run(){
fileProgressBar.setValue(x);
fileProgressBar.setString(String.valueOf (x)+"%");
}
});
}
}
}
}catch(Exception ex){
System.out.println("Chat.fileReciveHandler.run() "+ex.getMessage());
}finally{
try{
raf.close();
netIn.close();
in.close();
socket.close();
}catch(Exception e){}
}
}
}
public static void main(String[] args){
new fileRecieve();
}
}
不知道哪里出了点问题????总得来说功能可以实现!