socket通信(java实现)

本文介绍了基于Java的Socket通信,讲解了TCP/IP五层模型,指出所有通信底层都基于socket,Java通过封装提供socket功能。详细阐述了socket解析过程,以及如何在应用层、传输层、网络层等进行数据解析。同时,提供了客户端和服务端的简单代码实现,强调了启动顺序和并发处理的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、关于socket

  我们的应用程序是基于操作系统上的,把数据提交到操作系统中。所有通信的底层都是socket,而且所有的语言都是具有socket功能的。
但是,所有语言的socket模块,底层其实都是c语言的socket。所以c语言的socket负责沟通操作系统的内核对接,对接网卡
在这里插入图片描述
  socket是一门原理,一门技术。Java可以实现socket,并将其封装成一个类
通过ip地址,数据打到网卡上,而网卡上的数据通过相应的端口号把数据发送到当前的进程中

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

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

而socket解决了下面四层的封装。
在这里插入图片描述

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

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

在这里插入图片描述
在这里插入图片描述

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值