1. 程式人生 > >【Java小專案】一個Socket連續傳輸多個檔案

【Java小專案】一個Socket連續傳輸多個檔案

      想給前短時間做的那個山寨QQ加一個傳輸檔案的功能,因為那個山寨QQ每個客戶端和伺服器端就一個Socket連線用ObjectOutputStream進行通訊,現在要加一個DataOutputStream來傳輸檔案,所以先了寫這個試驗下。

     思路:

             1.在傳送DataOutputStream位元組流前先發一個Object來通知接受端。

             2.用writeLong通知接收端該檔案的長度。

             3.用writeUTF傳送檔名稱

             4.接受端用接受到的檔案長度來跳出讀檔案的迴圈

             5.(缺點)接收檔案的時候不能在接收Object資訊

程式碼如下

      Server

package com.server;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by ztc on 15-11-16.
 */
public class MyServer extends JFrame implements ActionListener{
    ServerSocket ss=null;
    Socket s=null;

    JFileChooser jfc;
    JButton jb,jb1;
    JTextArea jta;
    ObjectOutputStream oos;
    public static void main(String[] args){
        MyServer ms=new MyServer(8888);
        //ms.SendFile();
    }
    public MyServer(int port) {
        jfc=new JFileChooser();
        jb=new JButton("傳輸檔案");
        jb.addActionListener(this);
        jb1=new JButton("SendObject!");
        jb1.addActionListener(this);
        jta=new JTextArea();
        jta.setEditable(false);
        jta.setAutoscrolls(true);
        this.add(jta,"Center");
        this.add(jb,"South");
        this.add(jb1,"North");

        this.setVisible(true);
        this.setLocation(500,300);
        this.setSize(300,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        try {
            ss=new ServerSocket(port);
            System.out.println("Server is running...on"+port);
            s=ss.accept();
            oos=new ObjectOutputStream(s.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public void SendFile(File f,Object o){
        try {
            oos.writeObject(o);
            oos.flush();

            DataInputStream dis=new DataInputStream(new FileInputStream(f));
            DataOutputStream dos=new DataOutputStream(s.getOutputStream());
            //ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
            //oos.writeObject(f);
            dos.writeLong(f.length());
            dos.writeUTF(f.getName());
            System.out.println("長度:"+f.length());
            int count=-1,sum=0;
            byte[] buffer=new byte[1024*1024];
            while((count=dis.read(buffer))!=-1){
                dos.write(buffer,0,count);
                sum+=count;
                System.out.println("以傳輸"+sum+"byte");
            }
            System.out.println("傳送完畢!");
            dos.flush();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void SendObject(Object o){
        try {
            oos.writeObject(o);
            oos.flush();
            System.out.println("Sended Object!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==jb){
            jfc.setCurrentDirectory(jfc.getCurrentDirectory());
            int result=jfc.showOpenDialog(this);
            File f=jfc.getSelectedFile();
            if(result==0&&f!=null){
                SendFile(f,"File");
            }
        }else if(e.getSource()==jb1){
            SendObject("hello Im Server!");
        }
    }
}

Client
package com.client;

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

/**
 * Created by ztc on 15-11-16.
 */
public class MyClient{
    static Socket s = null;
    public static void main(String[] args) {
        MyClient my=new MyClient("127.0.0.1", 8888);
    }

    public MyClient(String host, int port) {

        try {
            s=new Socket(host,port);
            System.out.println("Data running>>>");
            ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
            while (true) {
                String type=(String)ois.readObject();
                System.out.println(type);
                if(type.equals("File")){
                    new FileTransport(s).run();
                }
                System.out.println("Object接受完畢!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

工具類
package com.client;

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

/**
 * Created by ztc on 15-11-17.
 */
public class FileTransport {
    Socket s;
    public FileTransport(Socket s){
        this.s=s;
    }
    public void run(){
        try {
            System.out.println("Thread running>>>");
            DataInputStream dis = new DataInputStream(s.getInputStream());
            long length=dis.readLong();
            String name=dis.readUTF();
            DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File(name)));
            int count=-1,sum=0;
            byte[] buffer=new byte[1024*1024];
            while((count=dis.read(buffer))!=-1){
                dos.write(buffer,0,count);
                sum+=count;
                System.out.println("已結收" + sum + "位元");
                if(sum==length)
                    break;
            }
            dos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}