unix网络编程1 基础知识

Introduction

    1. 通过学习unix网络编程,在不使用任何库只使用api的情况下实现一个内置lua解释器的web服务器,实现简单的业务逻辑,比如通过cgi模式在web浏览器中显示图片,播放视频,可以在不重启服务器的情况下更新业务逻辑。
    1. 主要是学习unix网络编程做的笔记,其中将插入网络编程
      的基础知识,会有多进程版,I/O复用,多线程版本,每个web
      服务器的吞吐量,并发连接数我都会有测试,最后会有对比图。

基础知识

  • 要编写计算机网络通信程序,首先要确定的就是通信的协议(protocol)。一般认为web服务器是一个长时间运行的程序(deamon),它只是在响应来自网络的请求时才发送网络信息。协议的另外一端就是web客户程序,如某种浏览器。一般来说都是客户端向服务端发消息,服务端就一直等着。也有服务器向客户发起请求的异步回调(asynchronous callback)通信,但是一般还是如下图的客户端/服务器模式。

 图1-1 客户和服务器

  • 多个客户向一个服务器发送请求

这里写图片描述

  • web客户端和服务器使用TCP(Transmission Control Protocol,传输控制协议)通信。TCP又转而使用IP(Internet Protocol,网际协议)通信,IP通过链路层通信。下图表示通信层次【局域网的情况】.
    1. 观察到虽然应用层是使用某种应用通信协议,比如FTP,HTTP。传输层都是是使用TCP协议。
    2. 下图又展现了客户/服务端信息流的传送方向,客户把信息从上到下通过链路层传送到服务器端,服务端从链路层读取一直到应用层。

这里写图片描述

  • 如果客户/服务端要在广域网通信则需要使用路由器。如下图

这里写图片描述

  • OSI模型
    下图所示,我们只关心传输层,以及数据链路层1500字数据限制,其他层都可以不管。

这里写图片描述

  • 下面只介绍TCP,不介绍UDP,UDP相关资料请参考unix网络编程相关章节。TCP是一个复杂的、可靠的字节流协议。
    UDP不提供确认,序列号,超时,重传,RTT估算等机制。

    1. TCP提供客户与服务器之间的连接(connection),客户端先和服务器建立连接,连接之后才能交换数据,最后连接终止。
    2. TCP提供可靠性,当TCP发数据要求对端要发送一个确认。如果没有收到数据就会重传数据,并且等待比上一次更长的时间[这个有算法计算往返时间(round-trip time,RTT),多次失败以后才放弃。
      [注意TCP传送的数据不能保证100%正确,它只能保证客户端收到了没有,不保证正确性]
    3. TCP给每一个字节一个序号,对发送的数据进行排序。通过这种方式TCP接收端可以对乱序的数据根据序号进行排序,如果有一个字节是重复的(因为网络拥堵的情况重传了数据),接收端就可以通过相同的序号丢弃掉这个字节
    4. TCP提供流量控制(flow control).TCP会告诉对端任何时刻能够可以接收的数据有多少,这个叫做通知窗口(advertised window).任何时刻窗口接收缓冲区能够接收多少数据。
    5. TCP是全双工(full-duplex)的,既可以发数据,又可以接收数据,而且为每一个数据流方向都提供,流量控制,跟踪序列号等。
  • TCP的建立

  • 三路握手
    1. 服务端被动打开(passive open),通过调用socket、bind、listen三个函数来完成。
    2. 客户端主动打开(active open),通过调用connect函数来完成,这会导致TCP发送一个SYN分节(分节里面含有连接建立以后传送数据的初始序号)
    3. 服务器必须确认(ACK)客户的SYN,并且它也发送一个SYN(里面含有服务端在连接建立以后发送第一个字节数据的序号)
    4. 客户必须确认服务端的SYN。
      这种交换至少需要三个分组,所以称为三路握手(three-way handshake),下图表现三路握手
      下图中客户的初始序号是J,服务器的初始序号是K,ACK是下一次希望接受的序号。SYN和FIN都占了一个字节,所以ACK要加1。
      注:分节是什么?
      网络各层是交换的信息单位是协议数据单元(protocol data unit,PDU),分节(segment)就是对应与TCP传输层的PDU。分节的长度是有限的。每个分节所封装的数据可以是应用进程的字节流数据(就是tcp通过输出操作写到套接字中的数据),按顺序封装后传送给TCP接收端。下面这两剧很重要请注意,就是每个分节所封装的由应用进程的数据可能不完整,这取决于,对端所告知的最大分节大小,下面会讲,以及链路层的外出接口最大传输单元(MTU).ip层(ipv4)所接收的最大数据为65535字节,所以运输层的数据不能超过这个数,还有传达链路层超过1500字节会分片。

这里写图片描述

  • TCP选项

    1. MSS选项。通知对端它的最大分节大小(maximum segment size),发送端使用接收端的MSS值作为所发分节的最大大小。
    2. 窗口规模选项。TCP连接通知对端的最大窗口是65535
  • TCP连接终止
    TCP连接终止需要四个分节

    1. 应用进程主动关闭(active close),调用close函数实现,该端的TCP发送一个FIN分节,表示数据发送完毕。
    2. 接收端接收了这个FIN分节就会进行被动关闭(passive close),TCP还要给发送端一个确认。FIN放在排队的数据后面,作为一个文件结束符(end-of-file)传递给应用进程,对端接收到FIN以后就没数据读了。
    3. 一段时间后收到文件描述符的应用进程也会调用close函数这也会导致它的TCP向发送方发FIN分节。
    4. 接收到第二个FIN分节,发送端再确认这个分节。
      注意:第二步和第三部在FIN分节一起发送的时候就合并为一步。
      下图展示TCP连接终止

这里写图片描述

  • TCP状态转换图 TCP建立连接和连接终止
    黑线表示客户正常状态转换
    虚线表示服务器正常状态转化

这里写图片描述

  • 下图是一个从开始建立连接,指示对端分节大小,服务端可以接收单个分节的最大大小是1460字节,客户端是536字节。建立连接就可以发送数据了,最后结束是四个分节。

这里写图片描述

  • 端口号
    使用端口号来区分进程。
    唯一表示一台服务器,客户端通过众所周知端口号(well-konwn port)。
    客户端使用创输层临时分配的端口号。

  • 套接字对
    TCP连接的两端的端口号+ip地址

  • TCP端口号和并发服务器
    并发服务器通过主服务器派生子进程处理新的连接.
    比如在freebsd上启动一个服务器,端口号21,该主机多宿,ip地址12.106.32.254和192.168.42.1.服务器被动打开使用{* : 21,* : },服务器在任意本地接口(第一个 ),21端口号等待连接,这个称其为监听套接字,后面外地地址是用接收任意地址的客户的访问,所以用 * 表示.当服务器接收客户连接时,将连接交给子进程处理.连接建立后要把已连接套接字填入.
    这里写图片描述

  • 并发服务器让子进程处理客户
    这里写图片描述
  • 处理第二个客户,TCP客户主机第二个客户分配的端口号是1501
    这里写图片描述
  • 缓冲区大小
    ipv4定义了最小重组缓冲区大小(minimum reassembly buffer size),支持最小数据报大小是576字节.
    MSS最大值为65535
    以太网使用ipv4最大1460(tcp首部20字节,ipv4首部20字节)
    下面是重点注意
    每一个TCP套接字都有一个发送缓冲区,当某个应用进程调用write,内核从该应用进程复制数据到发送缓冲区,如果发送缓冲区放不下,应用进程进入睡眠.假设该套接字是阻塞的,内核不从write系统调用返回,直到应用进程缓冲区所有数据都复制到套接字发送缓冲区.从write返回仅仅表示应用进程数据复制到套接字发送缓冲区,并不表示对端接收到数据.
    这里写图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值