一、关于socket

  我们的应用程序是基于操作系统上的,把数据提交到操作系统中。所有通信的底层都是socket,而且所有的语言都是具有socket功能的。

但是,所有语言的socket模块,底层其实都是c语言的socket。所以c语言的socket负责沟通操作系统的内核对接,对接网卡

Java中socket的框架 java socket包_数据


  socket是一门原理,一门技术。Java可以实现socket,并将其封装成一个类

通过ip地址,数据打到网卡上,而网卡上的数据通过相应的端口号把数据发送到当前的进程中

二、TCP/IP五层模型(从下到上)

物理层,决定01比特流如何传输
链路层 决定数据在局域网如何传输
网络层 决定数据在广域网中如何传输
传输层 保证数据如何稳定传输的一层 比如TCP协议
应用层 应用层的任务是通过应用进程间的交互来完成特定网络应用,包含着各种协议

而socket解决了下面四层的封装。

Java中socket的框架 java socket包_服务器_02

三、socket解析

   网卡把数据变成bite数组,底层是socket负责解析为bite[]数组。
   物理层传输的是比特流。所谓的流,就是数组,比如比特流,就是bite[]。而底层socket的解析就是底层一段有01组成的数据,而这些数据上会有一定的位数记录着物理层,链路层,网络层和传输层协议,相应的位数在相应的层上解析数据。到了传输层会根据那种编码根据位数转换为数据让我们读取。而我们的应用层就是数据的输出部分。
   换成代码实现底层判断这个数组 bite[100],也是前多少位代表物理层协议,后多少位代表链路层,多少位代表网络层、传输层协议,但整个应用层部分是数据和协议交错在一起的。

四、socket代码实现

代码分成两个部分,服务端和客户端。

客户端

一般操作:
1、创建socket对象,填写socket要发送的ip和端口号,即发送给谁
2、获取用户的输入
3、将用户输入的数据写入到服务器,socket中

/**
 * 客户端
 * */
public class client {
    public static void main(String[] args) throws IOException {

        Socket socket=new Socket("192.168.122.1",4700);//哪个端口发送数据,发送到哪个ip
        //获取用户输入
        Scanner scanner=new Scanner(System.in);
        String input =scanner.next();

        //将用户输入的数据写入到服务器,socket中
        OutputStream stream=socket.getOutputStream();
        PrintWriter writer=new PrintWriter(stream);
        writer.println(input);
        writer.flush();//关闭writer写入流。
    }
}

服务器端

一般操作:
1、创建socket对象,并打开相应的接收端口
2、开启线程持续监听有没有访问请求
3、得到socket,读取数据

/**
 * 服务器端
 * */
public class server {
    public static void main(String[] args) throws IOException {
        //创建socket并打开端口
        ServerSocket serverSocket=new ServerSocket(4700);

        //开启线程持续监听有没有访问请求
        while(true){//死循环 while(true)
           Socket socket= serverSocket.accept();//阻塞监听,相当于一把锁,到了这里就死锁住,除非监听到数据才会向下执行
            System.out.println(socket.getRemoteSocketAddress()); //accept有一个返回值,数据会被封装到socket对象中,返回给socket

        //2.得到socket当中的数据,读取数据
            new Thread(()->{//创建线程,以防客户端连接后不发送数据,堵塞其他用户也不能发送数据
                try {
                    InputStream stream=socket.getInputStream(); //通过io流把数据换成000101的代码
                    BufferedReader reader=   new BufferedReader(new InputStreamReader(stream));//分组切割数据
                    System.out.println(reader.readLine());
                }catch (IOException e){
                    e.printStackTrace();
                }
            }).start();
        }
    }
   
}

之后启动先启动服务端,后启用客户端。在客户端发送请求,服务端就会收到请求。

Java中socket的框架 java socket包_数据_03


Java中socket的框架 java socket包_网络_04

  因为服务器端有阻塞监听,只有客户端发送数据的时候才会向下执行代码。所以,当多个客户端连接一台服务器端,只要第一个与服务器端建立连接的用户不发送数据,其他客户发送数据,客户端不会收到。
所以上面代码采用创建线程的方法解决这个bug。同样也可以采用线程池的方法来实现上述代码。