1. Socket回顾与I/0模型

1.1 Socket概述:

Socket,套接字就是两台主机之间逻辑连接的端点。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议端口。

1.2 Socket整体流程:

Socket编程主要涉及到客户端和服务端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,可以选择任意一个当前没有被其他进程使用的端口。客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。

image.png


1.3 代码实现

服务端代码:

package com.lagou.server;

import java.io.IOException;

import java.io.InputStream;

2. 客户端代码

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ServerDemo {

  public static void main(String[] args) throws Exception {

    //1.创建一个线程池,如果有客户端连接就创建一个线程, 与之通信

    ExecutorService executorService = Executors.newCachedThreadPool();

    //2.创建 ServerSocket 对象

    ServerSocket serverSocket = new ServerSocket(9999);

    System.out.println("服务器已启动");

    while (true) {

      //3.监听客户端

      Socket socket = serverSocket.accept();

      System.out.println("有客户端连接");

      //4.开启新的线程处理

      executorService.execute(new Runnable() {

        @Override

        public void run() {

          handle(socket);

       }

     });

   }

 }

  public static void handle(Socket socket) {

    try {

      System.out.println("线程ID:" + Thread.currentThread().getId()

          + "  线程名称:" + Thread.currentThread().getName());

      //从连接中取出输入流来接收消息

      InputStream is = socket.getInputStream();

      byte[] b = new byte[1024];

      int read = is.read(b);

      System.out.println("客户端:" + new String(b, 0, read));

      //连接中取出输出流并回话

      OutputStream os = socket.getOutputStream();

      os.write("没钱".getBytes());

   } catch (Exception e) {

      e.printStackTrace();

   } finally {

      try {

        //关闭连接

        socket.close();

     } catch (IOException e) {

        e.printStackTrace();

     }

   }

 }

}

客户端代码:

package com.lagou.client;

1.2 I/O模型

1.2.1 I/O模型说明

1. I/O 模型简单的理解:就是用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的

性能

2. Java 共支持 3 种网络编程模型/IO 模式:BIO(同步并阻塞)、NIO(同步非阻塞)、AIO(异步非阻塞)

阻塞与非阻塞

主要指的是访问IO的线程是否会阻塞(或处于等待)

线程访问资源,该资源是否准备就绪的一种处理方式

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

import java.util.Scanner;

public class ClientDemo {

  public static void main(String[] args) throws Exception {

    while (true) {

      //1.创建 Socket 对象

      Socket s = new Socket("127.0.0.1", 9999);

      //2.从连接中取出输出流并发消息

      OutputStream os = s.getOutputStream();

      System.out.println("请输入:");

      Scanner sc = new Scanner(System.in);

      String msg = sc.nextLine();

      os.write(msg.getBytes());

      //3.从连接中取出输入流并接收回话

      InputStream is = s.getInputStream();

      byte[] b = new byte[1024];

      int read = is.read(b);

      System.out.println("老板说:" + new String(b, 0, read).trim());

      //4.关闭

      s.close();

   }

 }

}