1. 程式人生 > >利用Socket實現多客戶端傳輸物件和傳輸檔案實現

利用Socket實現多客戶端傳輸物件和傳輸檔案實現

第一次洗部落格,純屬自己紀念,主要來源是慕課網的Socket通訊課程,實現課後任務多客戶端傳輸物件,自己遇到的最大問題是忘記給User類實現序列化介面。
客戶端實現:
package com.imooc.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {

	public static void main(String[] args) {
		try {
			Socket socket=new Socket("localhost",8888);
			OutputStream os=socket.getOutputStream();
			ObjectOutputStream oos=new ObjectOutputStream(os);//將位元組流變成物件流,程式到這裡還沒碼完
			User user=new User("tom","123");
			oos.writeObject(user);//序列化,User類需要實現序列化介面
//			oos.flush();
			/*
			 * 將位元組流包裝成print流
			 */
//			PrintWriter pw=new PrintWriter(os);
//			pw.write("使用者名稱:tom;密碼:456");
//			pw.flush();
			socket.shutdownOutput();
			//建立輸入流,接受來自伺服器的資訊
			InputStream is=socket.getInputStream();
			InputStreamReader isr=new InputStreamReader(is);
			BufferedReader br=new BufferedReader(isr);
			String info=null;
			while((info=br.readLine())!=null){
				System.out.println("我是客戶端,伺服器發回復訊息:"+info);
			}
			//關閉資源
			br.close();
			isr.close();
			is.close();
			oos.close();
//			pw.close();
			os.close();
			socket.close();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

伺服器實現:

package com.imooc.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * 基於tcp協議的Socket通訊
 * 伺服器端
 */
public class Server {

	public static void main(String[] args) {
		try {
			//1.建立伺服器端ServerSocket物件,並指定偵聽埠
			ServerSocket serverSocket=new ServerSocket(8888);
			System.out.println("***伺服器即將啟動,等待客戶端傳送請求***");
			int count=0;//統計客戶端數量
			while(true){
				//2.開始偵聽指定埠,接收到之後建立Socket物件
				Socket socket=serverSocket.accept();
				count++;
				
				ServerThread serverThread=new ServerThread(socket);
				serverThread.start();
				System.out.println("客戶端數量:"+count);
				InetAddress address=socket.getInetAddress();
				System.out.println("客戶端IP地址:"+address.getHostAddress());
				
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
伺服器執行緒實現:
package com.imooc.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

import javax.print.attribute.standard.MediaSize.ISO;

/*
 * 伺服器端執行緒處理
 */
public class ServerThread extends Thread{
	
	public Socket socket;
	public ServerThread(Socket socket){
		this.socket=socket;
	}
	
	public void run(){
		InputStream is=null;
		InputStreamReader isr=null;
		BufferedReader br=null;
		OutputStream os=null;
		PrintWriter pw=null;
		ObjectInputStream ois=null;
		try {
			//3.通過getInputStream方法,接收來自客戶端的輸入流
			/*
			 * 從客戶端接受物件型別資料
			 */
			is=socket.getInputStream();
			ois=new ObjectInputStream(is);
			User user=(User) ois.readObject();//讀取物件資料的方法
			System.out.println("我是伺服器,客戶端發來訊息:"+"使用者名稱:"+user.getUsername()+";密碼:"+user.getPassword());
			/*
			 * 從客戶端接受字串資料
			 */
//			isr=new InputStreamReader(is);
//			br=new BufferedReader(isr);
//			String info=null;
//			while((info=br.readLine())!=null){
//				System.out.println("我是伺服器,客戶端發來訊息:"+info);
//			}
			//4.建立輸出流,準備輸出資訊給客戶端
			os=socket.getOutputStream();
			pw=new PrintWriter(os);
			pw.write("歡迎您");
			pw.flush();
			
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				socket.shutdownInput();
				//關閉其他資源
				if(pw!=null){
					pw.close();
				}
				if(os!=null){
					os.close();
				}
//				br.close();
//				isr.close();
				if(ois!=null){
					ois.close();
				}
				if(is!=null){
					is.close();
				}
				if(socket!=null){
					socket.close();
				}
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
User類實現:
package com.imooc.test;

import java.io.Serializable;

public class User implements Serializable{
	private String username;
	private String password;

	public User(String username, String password) {
		this.username = username;
		this.password = password;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}

最後在原程式的基礎上,稍加修改,實現檔案傳送。修改的部分僅伺服器執行緒類和客戶端類

伺服器執行緒實現,我在D盤的FIle檔案下新建了一個Server.txt檔案

package com.imooc.test1;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

import javax.print.attribute.standard.MediaSize.ISO;

/*
 * 伺服器端執行緒處理
 */
public class ServerThread extends Thread{
	
	public Socket socket;
	public ServerThread(Socket socket){
		this.socket=socket;
	}
	
	public void run(){
		InputStream is=null;
		InputStreamReader isr=null;
		BufferedReader br=null;
		OutputStream os=null;
		PrintWriter pw=null;
		ObjectInputStream ois=null;
		try {
			//3.通過getInputStream方法,接收來自客戶端的輸入流
			/*
			 * 從客戶端接受物件型別資料
			 */
			is=socket.getInputStream();
			ois=new ObjectInputStream(is);
			User user=(User) ois.readObject();//讀取物件資料的方法
			System.out.println("我是伺服器,客戶端發來訊息:"+"使用者名稱:"+user.getUsername()+";密碼:"+user.getPassword());
			/*
			 * 從客戶端接受字串資料
			 */
//			isr=new InputStreamReader(is);
//			br=new BufferedReader(isr);
//			String info=null;
//			while((info=br.readLine())!=null){
//				System.out.println("我是伺服器,客戶端發來訊息:"+info);
//			}
			//4.建立輸出流,準備輸出檔案給客戶端
			os=socket.getOutputStream();
			/*
			 * 這就是將輸出流包裝成物件輸出流的方式來輸出檔案
			  	ObjectOutputStream obj=new ObjectOutputStream(os);
			 * 
			 */
			 //這裡是將位元組輸出流包裝成緩衝輸出流來輸出檔案
			   BufferedOutputStream obj=new BufferedOutputStream(os);
				File file=new File("D:"+File.separator+"File"+File.separator+"Server.txt");
				FileInputStream fis=new FileInputStream(file);
				byte[] sendByte=new byte[1024];
				int length;
				while((length=fis.read(sendByte,0,sendByte.length))!=-1){
				obj.write(sendByte,0,length);
				obj.flush();
			}
			 
			
			
			
			
			
			
//			pw=new PrintWriter(os);
//			pw.write("歡迎您");
//			pw.flush();
			
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				socket.shutdownInput();
				//關閉其他資源
				if(pw!=null){
					pw.close();
				}
				if(os!=null){
					os.close();
				}
//				br.close();
//				isr.close();
				if(ois!=null){
					ois.close();
				}
				if(is!=null){
					is.close();
				}
				if(socket!=null){
					socket.close();
				}
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
客戶端實現:
package com.imooc.test1;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {

	public static void main(String[] args) {
		try {
			Socket socket=new Socket("localhost",8888);
			OutputStream os=socket.getOutputStream();
			ObjectOutputStream oos=new ObjectOutputStream(os);//將位元組流變成物件流,程式到這裡還沒碼完
			User user=new User("tom","123");
			oos.writeObject(user);//序列化,User類需要實現序列化介面
//			oos.flush();
			/*
			 * 將位元組流包裝成print流
			 */
//			PrintWriter pw=new PrintWriter(os);
//			pw.write("使用者名稱:tom;密碼:456");
//			pw.flush();
			socket.shutdownOutput();
			//建立輸入流,接受來自伺服器的資訊
			InputStream is=socket.getInputStream();
//			ObjectInputStream ois=new ObjectInputStream(is);  
			BufferedInputStream ois=new BufferedInputStream(is);
			File file=new File("D:"+File.separator+"File"+File.separator+"Client.txt");
			FileOutputStream fos=new FileOutputStream(file);
			byte[] buf=new byte[1024];
			int length;
			//ObjectInputStream的read方法,將資料寫入buf,從0開始讀,最大讀取的長度為緩衝陣列的長度。返回的為讀取位元組數的實際長度,到達末尾時返回-1
			while((length=ois.read(buf, 0, buf.length))!=-1){
				fos.write(buf, 0, length);
				fos.flush();
				System.out.println("客戶端這個時候正在接收資料");
			}
			
			
//			InputStreamReader isr=new InputStreamReader(is);
//			BufferedReader br=new BufferedReader(isr);
//			String info=null;
//			while((info=br.readLine())!=null){
//				System.out.println("我是客戶端,伺服器發回復訊息:"+info);
//			}
			//關閉資源
			fos.close();
			ois.close();
//			br.close();
//			isr.close();
			is.close();
			oos.close();
//			pw.close();
			os.close();
			socket.close();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}