socket.setSoTimeout(1000);


這個用來設置與socket的inputStream相關的read操作阻塞的等待時間,超過設置的時間了,假如還是阻塞狀態,會拋出異常java.net.SocketTimeoutException: Read timed out

這里的阻塞不是指read的時間長短,可以理解為沒有數據可讀,線程一直在這等待

 

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;

public class Server {
    private static final int PORT = 20000;

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket();
        // 是否復用未完全關閉的地址端口
        server.setReuseAddress(true);
        // 等效Socket#setReceiveBufferSize
        server.setReceiveBufferSize(64 * 1024 * 1024);
        // 設置serverSocket#accept超時時間
       // server.setSoTimeout(2000);
        // 設置性能參數:短鏈接,延遲,帶寬的相對重要性
        server.setPerformancePreferences(1, 1, 1);
        // 綁定到本地端口上
        server.bind(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 50);
        System.out.println("服務器start~");
        System.out.println("服務器信息:" + server.getInetAddress() + " P:" + server.getLocalPort());


        // 等待客戶端連接
        for (; ; ) {
            // 得到客戶端
            Socket client = server.accept();
            // 客戶端構建異步線程
            ClientHandler clientHandler = new ClientHandler(client);
            // 啟動線程
            clientHandler.start();
        }

    }



    /**
     * 客戶端消息處理
     */
    private static class ClientHandler extends Thread {
        private Socket socket;

        ClientHandler(Socket socket) {
            this.socket = socket;
        }
        @Override
        public void run() {
            System.out.println("新客戶端連接:" + socket.getInetAddress() + " P:" + socket.getPort());
            try {
                // 得到套接字流
                OutputStream outputStream = socket.getOutputStream();
                InputStream inputStream = socket.getInputStream();

                byte[] buffer = new byte[256];
                int readCount = inputStream.read(buffer);
                ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, readCount);

                // int
                int i = byteBuffer.getInt();
                // String
                int pos = byteBuffer.position();
                
                String str = new String(buffer, pos, readCount - pos);

                System.out.println("收到數量:" + readCount + " 數據:"
                        + i + "\n "
                        + str + "\n");

                 // 這里可以測試socketimeout異常 ,  即 在客戶端設置 socket.setSoTimeout(5000);
                 //而服務端一直沒有回寫數據,在客戶端就會拋出 java.net.SocketTimeoutException: Read timed out
//               outputStream.write(buffer, 0, readCount);
//               outputStream.close();
//               inputStream.close();
                
                Thread.sleep(8000);
            } catch (Exception e) {
                System.out.println("連接異常斷開");
            } finally {
                System.out.println("連接關閉");
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("客戶端已退出:" + socket.getInetAddress() +
                    " P:" + socket.getPort());
        }
    }
}

 

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;

public class Client {
    private static final int PORT = 20000;
    private static final int LOCAL_PORT = 20001;

    public static void main(String[] args) throws IOException {
        Socket  socket = new Socket();
         //設置讀取超時時間為2秒
         socket.setSoTimeout(5000);
        // 是否需要在長時無數據響應時發送確認數據(類似心跳包),時間大約為2小時
        //socket.setKeepAlive(true);
        // 設置接收發送緩沖器大小
        socket.setReceiveBufferSize(64 * 1024 * 1024);
        socket.setSendBufferSize(64 * 1024 * 1024);
        // 綁定到本地20001端口
        socket.bind(new InetSocketAddress(Inet4Address.getLocalHost(), LOCAL_PORT));
        // 鏈接到本地20000端口,超時時間3秒,超過則拋出超時異常
        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), PORT), 3000);

        System.out.println("已發起服務器連接,並進入后續流程~");
        System.out.println("客戶端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort());
        System.out.println("服務器信息:" + socket.getInetAddress() + " P:" + socket.getPort());

        try {
            // 發送接收數據
            todo(socket);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("異常關閉");
        }finally {
            // 釋放資源
            socket.close();
            System.out.println("客戶端已退出~");    
        }
    }




    private static void todo(Socket client) throws IOException  {
        // 得到Socket輸出流       , 輸入流
        OutputStream outputStream  =  client.getOutputStream();
        InputStream inputStream = client.getInputStream();
        byte[] buffer = new byte[256];
        ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);

        // int
        int i = 2323123;
        byteBuffer.putInt(i);

        // String
        String str = "Hello你好!";
        byteBuffer.put(str.getBytes());

        // 發送到服務器
        outputStream.write(buffer, 0, byteBuffer.position());

        // 接收服務器返回
        int read  = inputStream.read(buffer);
        System.out.println("收到數量:" + read);
        
        // 資源釋放
        outputStream.close();
        inputStream.close();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM