我是靠谱客的博主 大方盼望,最近开发中收集的这篇文章主要介绍高并发基础之Socket入门1 问题背景2 什么是Socket3 TCP的三次握手4 Socket三次握手5 客户端单向通信服务端例子,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在这里插入图片描述

文章目录

  • 1 问题背景
  • 2 什么是Socket
  • 3 TCP的三次握手
  • 4 Socket三次握手
    • 4.1 模型概览
    • 4.2 具体函数
  • 5 客户端单向通信服务端例子

1 问题背景

毕业设计做高并发相关的研究,前面粗略研究了解决高并发的核心——LinuxIO模型,笔者认为需要再粗略研究Socket相关的问题。

参考自:Socket技术详解(看清Socket编程)

2 什么是Socket

计算机之间通信需要知道对方的地址,Socket就是存储这个地址,实质上Socket是IP加端口号,格式是xx.xx.xx.xx:xxxx。如下图所示:
在这里插入图片描述
Socket可以理解成处于应用层与传输层之间。类比传输层的TCP三次握手,Socket也有三次握手,介绍Socket三次握手之前,先回顾TCP的三次握手。

3 TCP的三次握手

模型图如下:

在这里插入图片描述
如上图所示,客户端A主动发送SYB数据包,服务端B接收到后发送确认给A,A收到后对此确认发送确认数据包,A的连接建立了,B收到确认后也建立了连接。

4 Socket三次握手

4.1 模型概览

模型图如下:

在这里插入图片描述

4.2 具体函数

此处给出客户端单向发送数据给服务端为例子讲解。双向通信的例子还未研究。本以为双向通信很简单,然而写玩代码做测试的时候才发现没有想象中那么容易。

在这里插入图片描述

5 客户端单向通信服务端例子

场景:使用BIO方式实现,服务端监听客户端发来的连接请求,启动子线程处理客户端发来的信息。参考自B站的尚硅谷Netty教学视频

@Slf4j
public class BioServer {

    public static void main(String[] args) {
        // 阿里开发规范必须指定参数来构造线程池
        ThreadPoolExecutor serverPoolExecutor = new ThreadPoolExecutor(10,
                20,
                10,
                TimeUnit.MINUTES,
                new LinkedBlockingDeque<>(10),
                new DefaultThreadFactory("server-pool"));
        // 服务端创建socket
        try {
            ServerSocket serverSocket = new ServerSocket(8099);
            log.info("服务端已启动");

            while (true) {
                log.info("服务端等待连接");
                Socket socket = serverSocket.accept();
                log.info("主线程" + Thread.currentThread().getId() + "接收到一个客户端请求连接");
                // 创建线程池,启动一个线程去与客户端通信
                serverPoolExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        // 处理客户端的信息
                        handler(socket);
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void handler(Socket socket) {
        try{
            // 存储客户端发来的信息
            byte[] bytes = new byte[1024];
            InputStream inputStream = socket.getInputStream();
            while (true) {
                log.info("等待客户端发来数据...");
                // 从socket中读取发来的信息
                int read = inputStream.read(bytes);
                if (read != -1) {
                    // 输出客户端发来的信息
                    log.info("线程" + Thread.currentThread().getId() + "接收到数据:" + new String(bytes, 0, read));
                } else {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭与客户端的连接
            try {
                socket.close();
                log.info("客户端已关闭连接");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

使用telnet命令模拟客户端,ip和端口号是根据上面代码中的来的。输入telnet 127.0.0.1 8099。即可连接到服务端,按ctrl + ]可以进入发送数据的状态,使用send xxx命令发送数据。如下:

在这里插入图片描述

在这里插入图片描述

最后

以上就是大方盼望为你收集整理的高并发基础之Socket入门1 问题背景2 什么是Socket3 TCP的三次握手4 Socket三次握手5 客户端单向通信服务端例子的全部内容,希望文章能够帮你解决高并发基础之Socket入门1 问题背景2 什么是Socket3 TCP的三次握手4 Socket三次握手5 客户端单向通信服务端例子所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(30)

评论列表共有 0 条评论

立即
投稿
返回
顶部