【Java小專案】一個Socket連續傳輸多個檔案
阿新 • • 發佈:2019-02-11
想給前短時間做的那個山寨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();
}
}
}