当前位置: 首页 > news >正文

网络编程:Posix API

1 Posix API

服务器端:

  • socket():创建套接字
  • bind():绑定ip地址、端口等信息到socket上
  • listen():监听
  • accept():等待客户请求
  • send():发送数据
  • recv():接收数据
  • close():关闭连接

客户端:

  • socket():创建套接字
  • bind():绑定ip地址、端口等信息到socket上(可选)
  • connect():连接服务器
  • send():发送数据
  • recv():接收数据
  • close():关闭连接

注:客户端可以绑定(bind),绑定即确定了一个固定的端口,若不绑定,则会选择任意可用端口

socket

int socket(int domain, int type, int protocol);

domain:通信协议,常用AF_INET(IPv4) 和 AF_INET6(IPv6)
type:数据传输方式,常用SOCK_STREAM(字节流)和SOCK_DGRAM(报文)
protocol:传输协议,通常为0

socket包含了一个文件描述符(sockfd)与tcp控制块这两个信息。

在此函数实现了两个功能:
(1)分配fd
fd的分配使用了一个bitmap的算法

被占用为1,未被占用为0

第0位第1位第2位第3位第4位第5位第6位第7位
11101111

下一次需要使用的时候,会分配第3位
(2)分配tcp控制块的信息(包含了TCP为连接维护的信息:两个方向的序号,窗口大小,重传次数等的信息)

bind

int bind(int sockfd, const struct *sockaddr addr, socklen_t addrlen);

绑定sockfd和ip、端口

listen

int listen(int sockfd, int backlog);

(1)将TCP连接的状态设置成LISTEN状态
(2)分配全连接队列(accept_queue)和半连接队列(syn_queue)

在这里插入图片描述

上图为3次握手的情况。

当客户端请求连接,服务器监听到连接后,服务端将其加入到syn队列,并且响应syn+ack报文;等到客户端发送ack应答报文时,服务端将该连接从半连接队列中取出,加入到accept队列当中。

a. tcp连接的生命周期,从什么时候开始?
listen()的时候就会创建连接了

b. 第三次握手数据包,如何从半连接队列查找匹配的节点?
通过五元(源端口,目的端口,源ip,目的ip,协议)

c. syn泛洪
客户端不断建立连接(第一次握手),但始终不回复第三次握手

listen(fd, backlog),backlog的含义:

  • 最早的版本:backlog即为半连接(syn)队列长度
    • 可以防止syn泛洪,但由于现在有防火墙等方式处理syn泛洪,因此无需使用backlog避免syn泛洪
  • 后面的版本:syn + accept队列总长度(未被分配fd的tcb的数量)
    • 防止长时间不处理
  • 现在的版本:accept队列的长度
    • 提升建链的吞吐量

accept

(1)分配fd给对应的客户端
(2)将fd与tcb进行映射

send/recv

ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t recv(int sockfd, void *buf, size_t len, int flags);

send将应用程序拷贝到内核wmem中,由内核负责发送数据,recv则从内核rmem拷贝到应用程序中。

下图可以看到,进行了三次send,内核仅发送了一次数据,当超过MTU(需加上header)时,会分多个包。

在这里插入图片描述

recv(fd, buffer, 1000, 0);for(i = 0; i < 10; i++)
{recv(fd, buffer, 100, 0);
}

以上两种方式区别不大,下面仅多次系统调用,但差别不大。下面那种方式会使得接收一次时,内核缓冲区仍有900字节未被缓存,若rmem过小,则影响其他连接,但若rmem很大,则无影响。

2 三次握手

TCP状态迁移图:

在这里插入图片描述

三次握手:

在这里插入图片描述

以下适用于P2P的场景,与UDP不同,仍有延迟确认、超时重传:
在这里插入图片描述

3 四次挥手

在这里插入图片描述

四次挥手不分客户端和服务器端,只有主动方和被动方。

主动方先调用close,close函数回收了fd,然后发了fin包;接收方recv()返回为0的包,即知道对方要关闭连接。后续流程如上图所示。

a. 假如左侧没有收到ack,而是先收到fin
根据迁移图,FIN_WAIT_1进入CLOSING状态,收到ACK后进入TIME_WAIT状态

b. 双方同时调用close,发送fin包

在这里插入图片描述

TCP半连接队列和全连接队列-CSDN博客

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • windows C++-并发和异步操作(上)
  • 国标非对称加密:RSA算法、非对称特征、js还原、jsencrypt和rsa模块解析
  • 汇量科技Mintegral发布全新产品矩阵:助力广告主高效增长与变现
  • go-zero中基本配置及获取参数
  • django.core.management.base.SystemCheckError
  • 阿布吞的基础使用——Ubuntu
  • 格式化字符串漏洞
  • 基于Qt的osg读取模型进度回调
  • 数据结构:栈(含源码)
  • [QNX] C++编程: 外部硬件加速器与SOC共享内存中使用NOCACHE的必要性与优化策略
  • jQuery实现图片轮播效果
  • Redis相关面试题(二)
  • Go框架选战:Gin、Echo、Fiber的终极较量
  • 力扣 | 递增子序列 | 动态规划 | 最长递增子序列、最长递增子序列的个数、及其变式
  • Python-调用pymysql库,执行插入语句
  • [deviceone开发]-do_Webview的基本示例
  • iOS 颜色设置看我就够了
  • overflow: hidden IE7无效
  • Python学习之路13-记分
  • React系列之 Redux 架构模式
  • sessionStorage和localStorage
  • SpingCloudBus整合RabbitMQ
  • Vue2 SSR 的优化之旅
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 闭包--闭包作用之保存(一)
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 前嗅ForeSpider教程:创建模板
  • 提醒我喝水chrome插件开发指南
  • 硬币翻转问题,区间操作
  • 用Visual Studio开发以太坊智能合约
  • 《天龙八部3D》Unity技术方案揭秘
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • #laravel 通过手动安装依赖PHPExcel#
  • (0)Nginx 功能特性
  • (1)SpringCloud 整合Python
  • (30)数组元素和与数字和的绝对差
  • (bean配置类的注解开发)学习Spring的第十三天
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (回溯) LeetCode 46. 全排列
  • (六)DockerCompose安装与配置
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .Net Core中Quartz的使用方法
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET 药厂业务系统 CPU爆高分析
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .NET框架
  • /3GB和/USERVA开关
  • @Transactional事务注解内含乾坤?
  • @Transient注解
  • [2021 蓝帽杯] One Pointer PHP