在进行通信之前,一般要先建立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通知他。

  

  

套接字:Socket的更多相关文章

  1. Linux进程间通信(八):流套接字 socket()、bind()、listen()、accept()、connect()、read()、write()、close()

    前面说到的进程间的通信,所通信的进程都是在同一台计算机上的,而使用socket进行通信的进程可以是同一台计算机的进程,也是可以是通过网络连接起来的不同计算机上的进程.通常我们使用socket进行网络编 ...

  2. Linux进程间通信(九):数据报套接字 socket()、bind()、sendto()、recvfrom()、close()

    前一篇文章,Linux进程间通信——使用流套接字介绍了一些有关socket(套接字)的一些基本内容,并讲解了流套接字的使用,这篇文章将会给大家讲讲,数据报套接字的使用. 一.简单回顾——什么是数据报套 ...

  3. 套接字socket 的地址族和类型、工作原理、创建过程

    注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...

  4. [置顶] Java套接字Socket编程

    1)概念 网络编程基本模型就客户端到服务器的模型,也就是我们常见的C/S模型.简单的说就是两个进程间相互通信的过程.即通信双方一方作为服务器等待客户端提出请求并给以回应,另一方作为客户端向服务器提出请 ...

  5. Java网络编程--套接字Socket

    一.套接字Socket IP地址标志Internet上的计算机,端口号标志正在计算机上运行的进程(程序). 端口号被规定为一个16位的0--65535之间的整数,其中,0--1023被预先定义的服务通 ...

  6. 套接字编程,创建套接字socket

    1.套接字地址结构: struct sockaddr { sa_family_t sa_family; char sa_data[14]; }; 其中,成员sa_family表示套接字的协议族类型,对 ...

  7. 什么是套接字(Socket)

    应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题.多个TCP连接或多个应用程序进程可能需要 通过同一个TCP协议端口传输数据.为了区别不同的应用程序进程和连 ...

  8. Java套接字Socket编程--TCP参数

    在Java的Socket中,主要包含了以下可设置的TCP参数. 属性 说明 默认值 SO_TIMEOUT 对ServerSocket来说表示等待连接的最长空等待时间; 对Socket来说表示读数据最长 ...

  9. pythonl练习笔记——PythonNet 套接字socket

    1 套接字socket 1.1 套接字概述 套接字,一种网络通讯工具:用于进行网络间的通信,是一种特殊文件类型, 套接字,是一个通信链的句柄,用于描述IP地址和端口,实现向网络发出请求或应答网络请求. ...

  10. 面向对象之套接字(socket)和黏包

    一丶套接字(socket) tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端 基于UDP协议的socket server端: import socket udp_sk = socke ...

随机推荐

  1. MySQL中使用SHOW PROFILE命令分析性能的用法整理

    show profile是由Jeremy Cole捐献给MySQL社区版本的.默认的是关闭的,但是会话级别可以开启这个功能.开启它可以让MySQL收集在执行语句的时候所使用的资源.为了统计报表,把pr ...

  2. 一道另类的区间dp题 -- P3147 [USACO16OPEN]262144

    https://www.luogu.org/problemnew/show/P3147 此题与上一题完全一样,唯一不一样的就是数据范围; 上一题是248,而这一题是262144; 普通的区间dp表示状 ...

  3. python里面的数学

    一.基本运算符 1.算数运算 2.比较运算 特殊情况:!= 不等于 新版本不支持 <> 不等号 3.赋值运算 4.逻辑运算 not : 非   非真即假,非假即真.   - and : 并 ...

  4. spring boot 实现mybatis拦截器

    spring boot 实现mybatis拦截器 项目是个报表系统,服务端是简单的Java web架构,直接在请求参数里面加了个query id参数,就是mybatis mapper的query id ...

  5. linux systemctl 常用用法简介

    主要介绍systemctl的几个功能如下: 1.查看某个服务的状态 2.关闭某个服务 3.开启某个服务 4.设置某个为开机自启动 5.关闭某个服务为开机不启动 6.查看所有开启启动的服务 1.查看某个 ...

  6. rpcbind.service启动失败

    新装的服务器,启动rpcbind.service通常失败,执行下面的两个命令经常卡死,一直不返回,也不报错 #systemctl start nfs-server.service #systemctl ...

  7. linux之vim配置及使用示例

    作者:tongqingliu 转载请注明出处:http://www.cnblogs.com/liutongqing/p/7056193.html linux之vim配置及使用示例 vi的三种模式: 一 ...

  8. day35(servlet 3.0)

    servlet3.0的问题 Servlet3.0与Servlet2.5提供了三个新特性: * 注解开发   :方便 * 文件上传   :有些API不是特别全. * 异步请求   :多线程的实现 注解开 ...

  9. Job Interview: Why Only 3 Questions Really Matter

    Even for the most fearless amongst us, job interviews can be nerve wracking. In order to give us the ...

  10. 20155326 第12周课堂实践总结(二)String类和Arrays类的学习

    20155326 第12周课堂实践总结(二)String类和Arrays类的学习 实践二 Arrays和String单元测试 实践题目 在IDEA中以TDD的方式对String类和Arrays类进行学 ...