zoukankan      html  css  js  c++  java
  • 套接字:Socket

      在进行通信之前,一般要先建立Socket连接,Socket编程是端到端的通信,往往意识不到中间经过了多少局域网,多少路由器,他能操作的是端到端协议之上的网络层和传输层。

      在网络层,Socket函数可以指定使用IPV4(AF_INET)或者IPV6(AF_INET6),还可以指定传输层协议使用TCP(SOCK_STREAM)还是UDP(SOCK_DGRAM)。

    1. 基于TCP的Socket函数的调用过程

      a. 调用 bind 函数,给这个Socket赋予一个IP和端口(绑定IP是因为机器可能有多个网卡,绑定端口是确定进程);

      b. 调用 listen 函数进行监听;

        内核中每个socket维护两个队列:一个已经建立连接的队列(三次握手完毕,处于established状态),一个还没有完全建立连接的队列(三次握手尚未完成,处于syn_rcvd状态)。

        服务端监听时,客户端可通过 connect 函数发起连接,三次握手时,内核会给客户端分配一个临时端口,握手成功后服务端的accept返回另一个socket。

        监听的socket和传输数据的socket是两个socket,前者叫做监听socket,后者叫做已连接socket。

        为什么需要两个socket?为了复用监听socket,提高性能。

      c. 服务端调用 accept 函数,拿出一个已经完成连接进行处理; 

      d. 连接建立成功后,双方通过read和write函数读写数据;

    1.1 socket 结构

      TCP的socket就是一个文件流,Linux中socket就是以文件的形式存在的。初次之外还存在文件描述符,写入和读出也是通过文件描述符。

      每个进程都有有一个数据结构 task_struc,里面指向一个文件描述符数组(fds),列出这个进程打开的所有文件的文件描述符。文件描述符是一个整数,是这个数组的下标。

      数组中的内容是一个指针,指向内核中所有打开的文件的列表(file list);

      每个文件都有一个 inode,普通文件的inode保存在硬盘上,socket的inode保存在内存中;

      在这个inode中,指向了socket在内核中的 socket结构

      socket主要是一个发送队列和接收队列,两个队列里面保存的是一个缓存sk_buff。这个缓存里面可以看到完整的包结构。

      下面是一个整体的结构图。

      

    2. 基于UDP的Socket函数的调用过程

      a. bind 一个IP和端口号;

      b. 不需要维护连接状态,一个socket就可以和多个客户端通信;

      c. 没有连接状态,所以每次通信都调用 sendto recvfrom,都可以传入IP和端口; 

      

    3. 连接的处理方式

    3.1 多进程方式

      Linux下通过fork子进程,让子进程去处理socket,在Linux内核中,会复制文件描述符列表,内存空间,当前程序执行到哪一行的记录;

      fork()子进程后会返回一个整数,代表子进程的ID;

      进程调用fork函数时,返回0代表为子进程,返回其他整数代表为父进程;

      

    3.2 多线程方式

      在Linux下,通过pthread_create创建一个线程,也是调用do_fork。

      

    3.3 IO多路复用,一个线程维护多个socket(轮询)

      一个线程监听全部的socket,通过select函数监听文件描述符集合,

      一旦有变化,就依次查看每个文件描述符

      将发生变化的文件描述符在fd_set对应的位设置为1 ,表示socket可读或者可写,

      然后继续监听;

    3.4 IO多路复用,基于事件通知

      事件通知在Linux中通过epoll函数实现,通过注册callback函数的方式,某个文件描述符发生变化时主动通知。

      Linux中通过epoll_create创建epoll对象,它本身也是一个文件,它里面有一个红黑树结构,保存着监听的所有socket

      当epoll_ctl添加一个socket的时候,其实是加入这个红黑树,同时红黑树的节点指向一个结构,这个结构挂在被监听的socket事件列表中。

      当一个socket来了一个事件之后,可以在这个列表中得到epoll对象,并调用callback通知他。

      

      

  • 相关阅读:
    extjs4 数据实体模型
    WPF实现MDI窗体的方法
    WPF中图形表示语法详解(Path之Data属性语法
    Wpf DataGrid 数据绑定 排序 删除
    WPF: 使用TestApi模拟用户输入
    extjs4 事件处理
    WPF触发器
    XPath语法 在C#中使用XPath示例
    WPF 4 中DataGrid的模板列做双向数据绑定
    extjs4 标准面板
  • 原文地址:https://www.cnblogs.com/virgosnail/p/10105703.html
Copyright © 2011-2022 走看看