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();
    }
}

 

转载于:https://www.cnblogs.com/moris5013/p/10638802.html

你可能感兴趣的:(java)