Java Socket實現簡易【單線程/多線程】的服務端與客戶端的交互

今天覆習了一下socket的知識,看了一些網上博客的代碼,參考了一下自己也照着寫了一個服務端與客戶端的互撩demo

首先寫一個客戶端

package j2se;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
 
public class Server {
 
    public static void main(String[] args) {
    	
       try {
    	//初始化服務器端socket
		ServerSocket serverSocket=new ServerSocket(8888);
		//等待客戶端連接
		System.out.println("等待連接");
		Socket socket=serverSocket.accept();
		System.out.println("服務器有連接進來了");
		
		
		//通過socket獲取字符流
		BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		//獲取輸入的字符流
 	   	BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
		//獲取客戶端的輸入流
		BufferedReader bufferedReader2=new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
		String msg;
		
		while(true){
			msg=bufferedReader2.readLine();
			if("bye".equals(msg)||msg==null){
				System.out.println("服務器端消息:\n"+msg);
				System.out.println("聊天結束!");
				break;
			}
			System.out.println("來自客戶端的消息:\n"+msg);
			
			System.out.println("服務器端輸入:");
 		    String str = bufferedReader.readLine();
 		    bufferedWriter.write(str);
 		    bufferedWriter.write("\n");
 		    bufferedWriter.flush();
		}
		socket.close();
		bufferedReader.close();
		bufferedReader2.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
       
    }
}

然後是客戶端,在字符流後面加上一個\n,作爲標識告訴服務端客戶端已經輸入完了

package j2se;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
 
public class Client {
 
    public static void main(String[] args) {
 
       try {
    	   Socket socket=new Socket("127.0.0.1", 8888);
    	  
    	   
    	   //通過socket獲取字符流
           BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    	   
    	   //獲取輸入的字符流
    	   BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
    	   //獲取服務器端的字符流
    	   BufferedReader bufferedReader2=new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
    	   
    	   while(true){
    		   System.out.println("客戶端輸入:");
    		   String str = bufferedReader.readLine();
    		   bufferedWriter.write(str);
    		   bufferedWriter.write("\n");
    		   bufferedWriter.flush();
    		   if("bye".equals(str)||str==null){
    			   System.out.println("聊天結束");
    			   break;
    		   }
    		   
    		   String msg=bufferedReader2.readLine();
    		   System.out.println("來自服務器端消息:\n"+msg);
    	   }
    	   socket.close();
    	   bufferedReader.close();
   		   bufferedReader2.close();
    	   
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
       
    }
}

分別運行起來

server

client

 用“bye”作爲聊天結束的標識,程序結束

但是這裏可以看到,我們現在的程序是單線程的,同一時間,要麼收消息,要麼發消息,不能同時進行。

下面就做一點修改,用多線程實現同時收發。對上面代碼做出修改,新增SendThread.java和ReceviceThread.java並且它們都繼承了Thread

SendThread.java

package socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

public class SendThread extends Thread {
	private Socket socket;
	
	public SendThread(Socket socket){
	     this.socket = socket;
	}
	
	public void run(){
		try {
			//通過socket獲取字符流
			BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		    //獲取輸入的字符流
		    BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
		    
		    while(true){
		    	System.out.println("請輸入:");
	    		   String str = bufferedReader.readLine();
	    		   bufferedWriter.write(str);
	    		   bufferedWriter.write("\n");
	    		   bufferedWriter.flush();
	    		   if("bye".equals(str)||str==null){
	    			   System.out.println("聊天結束");
	    			   break;
	    		   }
		    }
		   
		}  catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

ReceviceThread.java

package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class ReceviceThread extends Thread {
	private Socket socket;
	 
    public ReceviceThread(Socket socket) {
        this.socket = socket;
    }
    
    public void run(){
    	try {
			//獲取客戶端的輸入流
			BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
			String msg;
			while(true){
				msg=bufferedReader.readLine();
				if("bye".equals(msg)||msg==null){
					System.out.println("收到消息:\n"+msg);
					System.out.println("聊天結束!");
					break;
				}
				System.out.println("收到消息:\n"+msg);
			}
		}catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }

}

重新修改Server.java

package socket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			ServerSocket serverSocket=new ServerSocket(8888);
			//等待客戶端連接
			System.out.println("等待連接");
			Socket socket=serverSocket.accept();
			System.out.println("服務器有連接進來了");
			
			//啓動發送消息線程
            new SendThread(socket).start();
            //啓動接受消息線程
            new ReceviceThread(socket).start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

Client.java

package socket;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			Socket socket=new Socket("127.0.0.1",8888);
			// 啓動發送消息線程
            new SendThread(socket).start();
            // 啓動接受消息線程
            new ReceviceThread(socket).start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

在控制檯看到,我們可以一直向服務端發送消息,服務端也能一直受到消息或者發送消息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章