unix网络编程1 基础知识
2015-04-05 18:39
369 查看
Introduction
通过学习unix网络编程,在不使用任何库只使用api的情况下实现一个内置lua解释器的web服务器,实现简单的业务逻辑,比如通过cgi模式在web浏览器中显示图片,播放视频,可以在不重启服务器的情况下更新业务逻辑。主要是学习unix网络编程做的笔记,其中将插入网络编程
的基础知识,会有多进程版,I/O复用,多线程版本,每个web
服务器的吞吐量,并发连接数我都会有测试,最后会有对比图。
基础知识
要编写计算机网络通信程序,首先要确定的就是通信的协议(protocol)。一般认为web服务器是一个长时间运行的程序(deamon),它只是在响应来自网络的请求时才发送网络信息。协议的另外一端就是web客户程序,如某种浏览器。一般来说都是客户端向服务端发消息,服务端就一直等着。也有服务器向客户发起请求的异步回调(asynchronous callback)通信,但是一般还是如下图的客户端/服务器模式。多个客户向一个服务器发送请求
web客户端和服务器使用TCP(Transmission Control Protocol,传输控制协议)通信。TCP又转而使用IP(Internet Protocol,网际协议)通信,IP通过链路层通信。下图表示通信层次【局域网的情况】.
观察到虽然应用层是使用某种应用通信协议,比如FTP,HTTP。传输层都是是使用TCP协议。
下图又展现了客户/服务端信息流的传送方向,客户把信息从上到下通过链路层传送到服务器端,服务端从链路层读取一直到应用层。
如果客户/服务端要在广域网通信则需要使用路由器。如下图
OSI模型
下图所示,我们只关心传输层,以及数据链路层1500字数据限制,其他层都可以不管。
下面只介绍TCP,不介绍UDP,UDP相关资料请参考unix网络编程相关章节。TCP是一个复杂的、可靠的字节流协议。
UDP不提供确认,序列号,超时,重传,RTT估算等机制。
TCP提供客户与服务器之间的连接(connection),客户端先和服务器建立连接,连接之后才能交换数据,最后连接终止。
TCP提供可靠性,当TCP发数据要求对端要发送一个确认。如果没有收到数据就会重传数据,并且等待比上一次更长的时间[这个有算法计算往返时间(round-trip time,RTT),多次失败以后才放弃。
[注意TCP传送的数据不能保证100%正确,它只能保证客户端收到了没有,不保证正确性]
TCP给每一个字节一个序号,对发送的数据进行排序。通过这种方式TCP接收端可以对乱序的数据根据序号进行排序,如果有一个字节是重复的(因为网络拥堵的情况重传了数据),接收端就可以通过相同的序号丢弃掉这个字节
TCP提供流量控制(flow control).TCP会告诉对端任何时刻能够可以接收的数据有多少,这个叫做通知窗口(advertised window).任何时刻窗口接收缓冲区能够接收多少数据。
TCP是全双工(full-duplex)的,既可以发数据,又可以接收数据,而且为每一个数据流方向都提供,流量控制,跟踪序列号等。
TCP的建立
三路握手
服务端被动打开(passive open),通过调用socket、bind、listen三个函数来完成。
客户端主动打开(active open),通过调用connect函数来完成,这会导致TCP发送一个SYN分节(分节里面含有连接建立以后传送数据的初始序号)
服务器必须确认(ACK)客户的SYN,并且它也发送一个SYN(里面含有服务端在连接建立以后发送第一个字节数据的序号)
客户必须确认服务端的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选项
MSS选项。通知对端它的最大分节大小(maximum segment size),发送端使用接收端的MSS值作为所发分节的最大大小。
窗口规模选项。TCP连接通知对端的最大窗口是65535
TCP连接终止
TCP连接终止需要四个分节
应用进程主动关闭(active close),调用close函数实现,该端的TCP发送一个FIN分节,表示数据发送完毕。
接收端接收了这个FIN分节就会进行被动关闭(passive close),TCP还要给发送端一个确认。FIN放在排队的数据后面,作为一个文件结束符(end-of-file)传递给应用进程,对端接收到FIN以后就没数据读了。
一段时间后收到文件描述符的应用进程也会调用close函数这也会导致它的TCP向发送方发FIN分节。
接收到第二个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返回仅仅表示应用进程数据复制到套接字发送缓冲区,并不表示对端接收到数据.
相关文章推荐
- 【总结】【Unix网络编程】前言及基础知识
- 基础知识-如何分辨自己处于内网还是外网(公网)?是否有网络防火墙?是否支持UPnP?
- DOS命令初学者基础知识学习
- 色彩系列教程(1):基础知识
- 摄影基础知识汇总
- 建立个人网站的基础知识三:软件方面
- OLAP与OLTP的一些基础知识
- 标准化基础知识
- 00014.网络基础知识
- Linux下C语言编程--基础知识
- Google关键词广告基础知识问答
- 复习一下 .Net: delegate(委托)、event(事件) 的基础知识,从头到尾实现事件!
- 刻录基础知识之刻录方式
- 第二讲 Java语言基础知识
- 《基于RealSystem的远程教学系统》第二部分 基础知识及协议部分
- JAVA基础知识精华总结
- Netty2: 事件驱动的NIO框架(基础知识)
- 模块的一些基础知识
- IP地址基础知识
- 建立个人网站的基础知识二:美工方面