Java 簡單網(wǎng)絡(luò)對話程序

  • Java客戶套接字類 Socket

  • 服務(wù)器套接字類 ServerSocket

  • 字符串讀/寫類 BuffferedReader/PrintWriter。

  • 服務(wù)進(jìn)程首先被動打開一個監(jiān)聽端口,如8008,客戶進(jìn)程主動訪問這個端口,完成對話聊天前的TCP三次握手連接。TCP連接成功后,通信進(jìn)程的雙方具有兩個流(輸出流和輸入流)。邏輯上可將兩個流理解為兩個通信管道的全雙工通信模式,一個用于向?qū)Ψ桨l(fā)送數(shù)據(jù),另一個用于接收對方的數(shù)據(jù)。


    image.png
  • 套接字類有兩個基本的方法可以獲得兩個通信管道的入口:

    • Socket.getInputStream()方法可獲得輸入字節(jié)流的入口地址;
    • Socket.getOutputStream()方法可獲得輸出字節(jié)流的出口地址;
  • socket.close() 實現(xiàn)四次握手?jǐn)嚅_


    image.png

TCP客戶端

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

public class TCPClient {
    //嵌套字程序設(shè)計
    private Socket socket = null;
    
    //用于字符和字節(jié)轉(zhuǎn)換的變量
    private PrintWriter pw;
    private BufferedReader br;
    
    public TCPClient(String ip, String port) throws IOException{
        //主動向服務(wù)器發(fā)起連接,實現(xiàn)TCP中三次握手的過程
        socket = new Socket(ip, Integer.parseInt(port));
        
        //若不成功(網(wǎng)絡(luò)問題,地址錯誤,服務(wù)器資源緊張等),拋出錯誤,其錯誤信息交由調(diào)用者處理  
        //若成功,做下面兩件事
        
        //得到網(wǎng)絡(luò)輸出字節(jié)流地址,并裝飾成網(wǎng)絡(luò)輸出字符流
        OutputStream socketOut = socket.getOutputStream();
        pw = new PrintWriter(new OutputStreamWriter(socketOut,"GB2312"),true);
       // pw.flush();
        
        //得到網(wǎng)絡(luò)輸入流地址,并裝飾成網(wǎng)絡(luò)輸入字符流
        InputStream socketIn = socket.getInputStream();
        br = new BufferedReader(new InputStreamReader(socketIn,"GB2312"));       
    }
    
    public void send(String msg){
        pw.println(msg+"\n");
        pw.flush();
        //輸出字符流,由Socket調(diào)用系統(tǒng)底層函數(shù),經(jīng)網(wǎng)卡發(fā)送字節(jié)流
    }
    
    public String receive(){
        String msg;
        try{
            //從網(wǎng)絡(luò)輸入字符流中讀信息,每次只能接收一行信息
            //若不夠一行(無行結(jié)束符),該語句阻塞,直到條件滿足,程序才往下運行
            msg = br.readLine();        
        }catch(IOException ex){
            msg = null;
        }
        
        return msg;
    }
    
    public void close(){
        try{
            if(socket != null){
                //實現(xiàn)三次握手
                socket.close();
            }
        }catch(IOException ex){}
    }
    
    //模塊內(nèi)測試與運行,需要先運行TCPServer
//    
//    public static void main(String args[])throws IOException{
//        TCPClient tc = new TCPClient("127.0.0.1","8008");
//        ec.send("123456789"); //發(fā)送一行字符
//        System.out.println(ec.receive());//接受一行字符串并在屏幕上顯示
//        tc.close();
//        
//    }  
}


TCP服務(wù)器

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

public class TCPServer {
    private int port = 8008;
    //服務(wù)器嵌套字
    private ServerSocket serverSocket;
    
    public TCPServer()throws IOException{
        //開啟8008監(jiān)聽端口
        serverSocket = new ServerSocket(8008);
        System.out.println("服務(wù)器啟動");
    }
    
    private PrintWriter putWriter(Socket socket)throws IOException{
        OutputStream socketOut = socket.getOutputStream();//獲得輸出流緩沖區(qū)的地址
        return new PrintWriter(new OutputStreamWriter(socketOut,"GB2312"),true);
    }
    
    private BufferedReader getReader(Socket socket)throws IOException{
        InputStream socketIn = socket.getInputStream();//獲得輸入流緩沖區(qū)的地址
        return new BufferedReader(new InputStreamReader(socketIn,"GB2312"));
    }
    
    public void service(){
        //單客戶版本,每次只能同時和一個客戶建立通信連接
        while(true){
            Socket socket = null;
            try{
                //阻塞語句,監(jiān)聽并等待客戶發(fā)起連接,有連接請求就生成一個嵌套字
                socket = serverSocket.accept();
                //本地服務(wù)器觀測臺顯示請求的用戶信息
                System.out.println("新用戶:" + socket.getInetAddress());
                BufferedReader br = getReader(socket);//定義字符串輸入流
                PrintWriter pw = putWriter(socket); //定義字符串輸出流
                
                String msg;
                //阻塞語句,從輸入流讀入一行字符串
                while((msg = br.readLine())!=null){
                  pw.println("來自服務(wù)器:" + msg); //先輸出流輸出一行字符串
                 // pw.flush();
                  if(msg.equals("bye")) //如果客戶發(fā)送的消息為"bye",就結(jié)束通信
                      break;
                }
            }catch(IOException e){
                e.printStackTrace();
            }finally{
                try{
                    if(socket!=null)
                        socket.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
    
    public static void main(String args[])throws IOException{
        new TCPServer().service();
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容