套接字 Socket 基础理论理解

一、何为套接字
  • 套接字是指通过软件来实现作为插口或者插槽,一端插在客户端,一端插在服务端。
  • Socket 编程进行的时端到端的通信,往往意识不到中间经过多少局域网,多少路由器,因此,能设置的参数也只能时端到端的协议之上网络层和传输层。
  • 在网络层:Socket 函数需要指定是 IPV4 还是 IPV6,分别对应设置为 AF_INET 和 AF_INET6。
  • 在传输层:需要指定是 TCP 还是 UDP 。TCP 协议是基于数据流的,所以设置为 SOCK_STERAM,而 UDP 是基于数据报的,所以设置为 SOCK_DGRAM。
二、基于 TCP 协议的 Socket 程序函数调用过程
  • TCP 的服务端要监听一个端口,一般是先调用 bind 函数,给这个 Socket 赋予一个 IP 地址和端口。

  • 当服务端有了 IP 地址和端口号,就可以调用 listen 函数进行监听。客户端就可以发起连接了。

  • 在内核中,每个Socket 维护两个队列。

    • 已经建立连接队列,完成三次握手完毕,处于established 状态。
    • 未完成建立连接的队列,没有三次握手,处于 syn_rcvd 的状态。
  • 服务端调用 accept 函数,拿出一个已经完成的连接进行处理,如果还没有完成就要等着。

  • 在服务端等待的时候,客户端可以通过 connect 函数发起连接。先在参数中指明要连接的 IP 地址和端口号,然后发起三次握手。内核会给客户端分配一个临时的端口。一旦握手成功,服务端的 accep 就会返回另一个 Socket 。

  • 监听的 Socket 和真正用来传输数据的 Socket 是不同的两个,一个是叫做监听Socket,一个叫做已连接 Socket

  • 建立连接成功后,双方开始通过 read 和 write 函数来读写数据。

  • 具体连接如下图所示:

在这里插入图片描述

二、基于 UDP 协议的 Socket 程序函数调用过程
  • 因为 UDP 没有连接,所以不需要三次握手,也不需要listen 和connect。同时 UDP因为没有维护连接状态,所以,也不需要每对连接建立一组 Socket ,只需要一个 Socket 就能够和多个客户端通信。
  • UDP 也需要 IP 地址和端口号,因此也需要 bind 。每次通信时候,调用sendto 和recvfrom 就可以传入 IP地址和端口号。
  • 具体连接如下图所示:

在这里插入图片描述

三、服务器如何接更多的项目?
方式一:将项目外包给其他公司(多进程方式)
  • 相当于你是一个代理,一直监听请求,一旦建立一个连接,就会有一个已连接的Socket ,这时候就可以创建一个子进程,然后将基于连接 Socket 的交互交给这个新的子进程来做。
  • 在Linux下,创建进程用 FORK 函数。两个进程复制完成时候一模一样,通过返回值为 0 则判断为子进程,返回其他的整数,则判断为父进程。
  • FORK 的子进程和父进程完全一样,所以判断子进程是否完成了通信退出的方法是,父进程通过子进程的 ID 查看是否完成而选择是否退出。
方式二:将项目转包给独立的项目组(多线程方式)
  • 在 Linux 下,通过pthread_create 创建一个线程,也是调用 do_fork 。不同的是,虽然新的 task 列表会创建一项,但是很多资源还是共享的。子不是多了一个引用而已。
注:基于进程或者线程模型的通信方式,存在 C10K 问题,所谓 C10K 问题就是 1 台机器要维护 1 万个连接,就要创建 1 万个进程或者线程。显然这样是很不科学且实用的。
方式三:一个项目组支持多个项目(IO多路复用,一个线程维护多个 Socket)
  • 一个项目组可以看多个项目,通多项目进度墙来查看项目的进度。一旦项目有进展,就派人去盯一下。
  • 由于 Socket 是文件描述符,因而某个线程盯的 Socket ,都放在一个文件描述集合 fd_set 中,这就是项目墙。然后调用 select 函数来监听文件描述符集合是否有变化。
方式四:以恶搞项目组支撑多个项目(IO多路复用,从“派人盯着”到“有事通知”)
  • 由于方式三是通过轮询的方式来盯着这个项目,所以还是不够好。因此,采用 epoll 函数通过注册 callback 函数的方式,来当文件描述符发送变化的时候就主动通知。
  • 在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值