Socket學(xué)習(xí)

socket通過(guò)三次握手建立連接,通信完成時(shí)拆除連接
四要素是:客戶端地址,客戶端端口,服務(wù)端地址,服務(wù)端端口
客戶端和服務(wù)端的代碼編寫(xiě)
關(guān)于 Thread 類(lèi)(https://blog.csdn.net/qq_58266033/article/details/123638588)
在java標(biāo)準(zhǔn)庫(kù)中,提供了一個(gè)Thread類(lèi),用來(lái)表示/操作線程,Thread類(lèi)可以視為是Java標(biāo)準(zhǔn)庫(kù)提供的API,Java是支持多線程編程的,在Java中創(chuàng)建好的Thread實(shí)例,其實(shí)和操作系統(tǒng)中的線程是一一對(duì)應(yīng)的關(guān)系,操作系統(tǒng)提供了一組關(guān)于線程的API(C語(yǔ)言),Java對(duì)于這組API進(jìn)一步封裝之后就變成了Thread類(lèi)

最簡(jiǎn)單的創(chuàng)建線程方式 寫(xiě)一個(gè)類(lèi)繼承線程Thread類(lèi) 再重寫(xiě)run方法

服務(wù)端Server.java

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

public class Server {
    public static void main(String[] args) throws IOException {
        // 新建一個(gè)服務(wù)器socket  只需要設(shè)置端口即可  不需要設(shè)置ip
        ServerSocket server = new ServerSocket(2000);

        System.out.println("服務(wù)器準(zhǔn)備就緒--");
        System.out.println("服務(wù)器信息:"+server.getInetAddress()+" P:"+server.getLocalPort());

        // 無(wú)限循環(huán) 接收來(lái)自客戶端的請(qǐng)求
        for (;;){
            // 接受客戶端  獲得客戶端的client信息
            Socket client = server.accept();
            // 握手接收到以后 開(kāi)一個(gè)線程執(zhí)行線程里面的操作
            ClientHandler clientHandler = new ClientHandler(client);
            // 線程執(zhí)行
            clientHandler.start();
        }
    }

    // 新建一個(gè)類(lèi) 繼承線程里面的方法 
    private  static  class  ClientHandler extends  Thread{

        private Socket socket;
        private  boolean flag = true;

        ClientHandler(Socket socket){
            this.socket = socket;
        }
        
        //重寫(xiě)線程里面的run方法
        @Override
        public void run() {
            
            // 先繼承原有run方法
            super.run();
            // 打印出客戶端的相關(guān)信息 
            System.out.println("新客戶端連接:"+socket.getInetAddress()+" P:"+socket.getPort());

            try {
                //得到打印流 用于數(shù)據(jù)輸出;服務(wù)器
               //客戶端的輸出流 作為一個(gè)打印流 
                PrintStream socketOutput = new PrintStream(socket.getOutputStream());

                //客戶端的輸入流 轉(zhuǎn)換為BufferedReader 
                BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                do{
                    //客戶端拿到一條數(shù)據(jù)
                    //從打印流拿到數(shù)據(jù)
                    String str = socketInput.readLine();
                    if("bye".equalsIgnoreCase(str)){
                        flag=false;

                        socketOutput.println("bye");
                    }else {
                        System.out.println(str);
                        //輸出流往客戶端寫(xiě)東西   
                        socketOutput.println("回送"+str.length());
                    }
                }
                while (flag);

            }catch (Exception e){
                System.out.println("連接異常斷開(kāi)");
            }finally {
                try {
                    socket.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            System.out.println("客戶端已退出:"+socket.getInetAddress()+" P:"+socket.getPort());
        }
    }
}

客戶端Client.java

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

// 新建一個(gè)客戶端 
public class Client {

    // main函數(shù)
    public static void main(String[] args) throws IOException {
        
        // 新建一個(gè)socket
        Socket socket = new Socket();
        // 設(shè)置超時(shí)時(shí)間
        socket.setSoTimeout(3000);

        // 設(shè)置連接本地 端口2000;超時(shí)時(shí)間3000
        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(),2000),3000);

        System.out.println("已發(fā)起服務(wù)器連接,并進(jìn)入后續(xù)流程--");
        System.out.println("客戶端信息:"+socket.getLocalAddress()+" P:"+socket.getLocalPort());
        System.out.println("服務(wù)器信息:"+socket.getInetAddress()+" P:"+socket.getPort());
      
        //連接到服務(wù)器以后 做todo()方法的相關(guān)操作 傳入socket參數(shù)是為了得到服務(wù)器的輸入流和輸出流
        try {
            todo(socket);
        }catch (Exception e){
            System.out.println("異常關(guān)閉");
        }

         // 釋放資源
        socket.close();
        System.out.println("客戶端已退出");
    }

    public static void todo(Socket client) throws  IOException {
        
        // BufferedReader 從字符輸入流中讀取文本,緩沖各個(gè)字符,從而實(shí)現(xiàn)字符、數(shù)組和行的高效讀取。
        // 構(gòu)建鍵盤(pán)輸入流
        //將InputStreamReader轉(zhuǎn)為BufferedReader 
        InputStream inputStream= System.in;
        BufferedReader bufferedReader =  new BufferedReader(new InputStreamReader(inputStream));

        // 得到Client輸出流,并轉(zhuǎn)換為打印流
        // outputStream 直接轉(zhuǎn)換為PrintStream  打印流 
        OutputStream outputStream = client.getOutputStream();
        PrintStream socketPrintStream = new PrintStream(outputStream);

        // 得到Client輸入流,并轉(zhuǎn)換為BufferedRead 
        InputStream inputStream1 = client.getInputStream();
        BufferedReader bufferedReader1 = new BufferedReader(new InputStreamReader(inputStream1));
        boolean flag = true;
        do {
            //鍵盤(pán)讀取一行
            String str = bufferedReader.readLine();
            // 通過(guò)打印流發(fā)送到服務(wù)器
            socketPrintStream.println(str);
            //從服務(wù)器讀取一行
            String echo = bufferedReader1.readLine();
            // 如果是bye則不做操作 否則打印出來(lái)
            if ("bye".equalsIgnoreCase(echo)) {

            }else{
                System.out.println(echo);
            }
        }
        // 重復(fù)輸入 直到斷開(kāi)
        while(flag);
        //關(guān)閉socketPrintStream 釋放內(nèi)存
        socketPrintStream.close();
    }
}

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

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

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