JAVA 网络编程之 Socket
Socket (套接字)

用于描述IP地址和端口

ServerSocket 常用于服务器端,Socket是建立网络连接时使用的。

连接成功时,客户端与服务端都会产生一个Socket实例,通过对这个Socket的操作,来实现所需的会话。

对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。

Socket API
  • accept() 用于产生“阻塞” 知道接收到一个连接,并且返回一个客户端的Socket实例对象。
  • getInputStream() 获得网络连接并返回一个 InputStream对象 inputStream的关闭会导致Socket的关闭
  • getOutputStream() 连接的另一端将得到输入,同时返回一个OutputStream对象实例
TCP 编程
服务端实现步骤
  1. 创建ServerSocket 对象,绑定监听端口
  2. 调用accept() 方法监听客户端请求
  3. 通过输入流读取客户端发送的请求信息
  4. 通过输出流向客户端发送响应信息
  5. 关闭相应资源
	/**
     * 创建线程池
     */
    private static ExecutorService threadPool = Executors.newFixedThreadPool(20);

    /**
     * 创建服务端
     * @throws IOException
     */
    private static void createServer() throws IOException {
        while (true) {
            //监听端口 6000
            ServerSocket serverSocket = new ServerSocket(55533);
            //获取客户端信息
            Socket accept = serverSocket.accept();
            //是否启用心跳机制
            accept.getKeepAlive();
            //客户端与服务端建立连接时 新建任务 并提交该任务到线程池
            if (null != accept) {
                Runnable task = new Runnable() {
                    @Override
                    public void run() {
                        InputStream inputStream = null;
                        StringBuilder sb = new StringBuilder();
                        try {
                            inputStream = accept.getInputStream();
                            byte[] bytes = new byte[1024];
                            int len;
                            while ((len = inputStream.read(bytes)) != -1) {
                                //注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
                                sb.append(new String(bytes, 0, len, "UTF-8"));
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        System.out.println("我看到你了!!");
                        System.out.println("通话内容是: " + sb.toString());
                        System.out.println("端口 " + accept.getPort());
                        System.out.println("IP 地址 " + JSON.toJSONString(accept.getInetAddress()));

                        OutputStream outputStream = null;
                        try {
                            outputStream = accept.getOutputStream();
                            outputStream.write("老铁 我收到你消息了!!".getBytes("UTF-8"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                };
                threadPool.submit(task);
            }
        }
    }

==注意: == 在以上的代码中所有的 OutputStream 与 InputStream都没有关闭,因为流的关闭会导致 Socket 的关闭

客户端实现步骤
  1. 创建Socket对象,指明需要连接的服务器的地址和短括号
  2. 连接建立后,通过输出流向服务端发送请求信息
  3. 通过输入流读取服务器响应的信息
  4. 关闭相应资源
/**
     * 测试
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        int port = 55533;
        String host = "127.0.0.1";
        String msg ="我给你发消息了 老铁!!";
        sendMsg(port, host, msg);
    }

    /**
     * 发送消息
     * @param port
     * @param host
     * @param msg
     */
    private static void sendMsg(int port, String host, String msg) {
        Socket socket = null;
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            socket = new Socket(host, port);
            outputStream = socket.getOutputStream();

            if (StringUtils.isEmpty(msg)) {
                msg = "";
            }
            outputStream.write(msg.getBytes("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(null!=socket){
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        }
    }