IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Socket和网络编程 -> 正文阅读

[系统运维]Socket和网络编程


参考:

  1. 为什么网络IO会被阻塞
  2. 韩顺平网络多线程专题
  3. Java网络IO模型、阻塞与非阻塞、同步与异步

0、前言

0.1、IP、域名、端口号

0.1.1、IP

  1. IPv4使用4个字节(一个字节8位)表示,一个字节表示范围(0~255)。
  2. ip地址的组成=网络地址+主机地址,比如:192.168.16.92。
  3. IPv6使用16个字节表示,是IPv4地址长度的四倍。
  4. Ipv4地址分类:
    在这里插入图片描述

0.1.2、域名

  1. 例如:www.baidu.com
  2. 好处:为了方便记忆,解决记ip的困难。
  3. 概念:将ip地址映射成域名。

0.1.3、端口号

  1. 用于标识计算机上某个特定的网络程序。
  2. 范围:0~65535(常见的:mysql3306,tomcat8080,http80,…)。

0.1.4、数据进入协议栈的封装过程

在这里插入图片描述

0.2、Socket是什么?

  1. Socket(套接字)开发网络应用程序被广泛采用,以至于称为事实标准。
  2. 通信的两端都要有Socket,是两台机器之间通信的断点。
  3. 网络通信本质就是Socket通信。
  4. SOcket允许程序把网络连接当成一个流,数据在两个Socket之间通过IO传输。
  5. 一般主动发起通信的应用程序属于客户端,等待通信请求的为服务端。
  6. 通过Socket可以实现通信的读写数据。
    在这里插入图片描述
    在这里插入图片描述
  7. 一定要关闭socket,否则一旦连接过多,之后新的客户端再想连接就无法连接成功。
  8. 服务端指定端口号进行监听,客户端也会被随机分配一个端口进行通信,该端口是TCP/IP来分配的,是不确定的,随机的。

1、I/O是什么?

  1. I/O就是input和output的缩写,即:输入/输出。
  2. 磁盘I/O指的是硬盘和内存之间的输入和输出。
  3. 读取本地文件的时候,要将磁盘的数据拷贝到内存中,修改本地文件的时候,需要把修改后的数据拷贝到磁盘中。
  4. 当网络上的数据到来时,网卡需要将数据拷贝到内存中。当要发送数据给网络上的其他人时,需要将数据从内存拷贝到网卡里。
  5. 那为什么都要跟内存交互呢?
  6. 我们的指令最终是由 CPU 执行的,究其原因是 CPU 与内存交互的速度远高于 CPU 和这些外部设备直接交互的速度。
  7. 因此都是和内存交互,当然假设没有内存,让 CPU 直接和外部设备交互,那也算 I/O。
  8. 总结下:I/O 就是指内存与外部设备之间的交互(数据拷贝)

1.1 阻塞式I/O

在这里插入图片描述

package com.morris.bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class BioSingleThreadServer {

    public static final int PORT = 8899;

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

        ServerSocket serverSocket = new ServerSocket(); // socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 5
        //表示使用IPv6,使用字节流套接字,使用IP协议

        serverSocket.bind(new InetSocketAddress(PORT)); // bind(5, {sa_family=AF_INET6, sin6_port=htons(8899), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = 0
        // bind()里面会调用listen方法 listen(5, 50)

        System.out.println("server is start at " + PORT); //

        while (true) {
            try {
                Socket socket = serverSocket.accept(); // accept(3, {sa_family=AF_INET6, sin6_port=htons(34270), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [28]) = 5
                InputStream inputStream = socket.getInputStream();
                System.out.println("connect success " + socket.getPort());

                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

                System.out.println("receive from client: " + reader.readLine()); // recv(5, "hello\r\n", 8192, 0)           = 7

                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}

1.1.1、创建socket(服务端)

  1. 创建socket:首先服务端需要先创建一个socket。在Linux中一切都是文件,那么socket也是文件,每个文件都有一个整型的文件描述符(fd)来指代这个文件。
    int socket(int domain, int type, int protocol);
    
    1. domain:这个参数用于选择通信的协议族,比如选择 IPv4 通信,还是 IPv6 通信等等
    2. type:选择套接字类型,可选字节流套接字、数据报套接字等等。
    3. protocol:指定使用的协议。通常可以设置为0,因为可以由前面两个参数推出说需要使用的协议。
    4. 比如socket(AF_INET, SOCK_STREAM, 0);,表明使用 IPv4 ,且使用字节流套接字,可以判断使用的协议为 TCP 协议。
    5. 返回值为int,就是创建的socket的id。

1.1.2、bind(服务端)

  1. 此时创建了一个socket,但还没有地址指向这个socket。
  2. 服务器应用需要指明IP和端口,这样客户端才能指定与服务器那个端口进行通讯。此时需要指定一个地址和端口来与这个socket绑定。
  3. int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);,参数里面的sockfd就是创建的socket的文件描述符,执行了bind参数之后,socket被访问更近一步了。

1.1.3、listen(服务端)

  1. 此时socket还处于closed状态,即:不对外监听的,需要调用listen方法让socket进入被动监听的状态。
  2. int listen(int sockfd, int backlog);,sockfd是socket的的文件描述符,此时还要指明backlog。backlog就是队列的大小(socket有一个队列,同时存放已经完成的连接和半连接,backlog为这个队列的大小)。

1.1.4、accept(服务端)

  1. 初始化好监听套接字,此时会有客户端连接上来,需要处理这些已经完成建连的连接。
  2. 三次握手的连接会被加入到已完成连接队列中,此时需要从已经完成连接队列中拿到连接进行处理,拿取的动作由accept完成。
  3. int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  4. 如果已经完成连接队列没有连接可以取,那么调用accept的线程就会阻塞等待。
    在这里插入图片描述

1.1.5、connect(客户端)

  1. 客户端也需要创建一个socket,也就是调用socket()
  2. 客户端创建完socket并调用connect之后,连接就处于SYN_SEND状态,当收到服务端回传的连接确认报文段之后,连接就变为ESTABLISHED状态,此时三次握手完毕。
  3. int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);,调用connect需要指定远程的地址和端口进行建立连接,三次握手完毕之后就可以开始通信了。
  4. 客户端这边是不需要调用bind操作,默认会选择源IP和随机端口

此时从连接角度看,就有两个阻塞的点:

  • connect:需要阻塞等待三次握手完成。
  • accept:需要等待可用的已完成的连接,如果已完成连接队列为空,则被阻塞。

1.1.6、read、write

连接建立好之后就要进行读写数据。
在这里插入图片描述

  1. read 为读数据,从服务端来看就是等待客户端的请求,如果客户端不发请求,那么调用 read 会处于阻塞等待状态,没有数据可以读,这个应该很好理解。
  2. write 为写数据,一般而言服务端接受客户端的请求之后,会进行一些逻辑处理,然后再把结果返回给客户端,这个写入也可能会被阻塞。
  3. 由于采用TCP协议,TCP协议需要保证数据可靠、有序传输,并且给予段与段之间的流量控制,所以说发送不是直接发出去,它有个发送缓冲区,我们需要把数据先拷贝到 TCP 的发送缓冲区,由 TCP 自行控制发送的时间和逻辑,有可能还有重传什么的。
  4. 如果我们发的过快,导致接收方处理不过来,那么接收方就会通过 TCP 协议告知:别发了!忙不过来了。发送缓存区是有大小限制的,由于无法发送,还不断调用 write 那么缓存区就满了,满了就不然你 write 了,所以 write 也会发生阻塞。

1.1.6、总结

  1. 因为建连和通信涉及到的 accept、connect、read、write 这几个方法都可能会发生阻塞。
  2. 阻塞会占用当前执行的线程,使之不能进行其他操作,并且频繁阻塞唤醒切换上下文也会导致性能的下降。
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-12-23 16:04:59  更:2021-12-23 16:06:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 5:28:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码