Linux网络编程:7. TCP/IP协议

导读:
   7.1 网络传输分层
  如果你考过计算机等级考试,那么你就应该已经知道了网络传输分层这个概念。在网络上,人们为了传输数据时的方便,把网络的传输分为7个层次,分别是:应用层、表示层、会话层、传输层、网络层、数据链路层和物理层。分好了层以后,传输数据时,上一层如果要数据的话,就可以直接向下一层要了,而不必要管数据传输的细节;下一层也只向它的上一层提供数据,而不要去管其它东西了。如果你不想考试,你没有必要去记这些东西的。只要知道是分层的,而且各层的作用不同。
   7.2 IP协议
  IP协议是在网络层的协议。它主要完成数据包的发送作用。下面这个表是IP4的数据包格式:
  0 4 8 16 32
  +-------+-------+--------+---------------------+
  | 版本 |首部长度|服务类型|   数据包总长    |
  +-------+-------+--------+---+---+-------------+
  |     标识     |DF |MF |  碎片偏移  |
  +------------------------+---+---+-------------+
  |  生存时间  | 协议 |   首部较验和    |
  +---------------+--------+---------------------+
  |           源IP地址          |
  +----------------------------------------------+
  |           目的IP地址         |
  +----------------------------------------------+
  |           选项            |
  +==============================================+
  |           数据            |
  +----------------------------------------------+
  下面我们看一看IP的结构定义 :
  struct ip
  {
  #if __BYTE_ORDER == __LITTLE_ENDIAN
  unsigned int ip_hl:4; /* header length */
  unsigned int ip_v:4; /* version */
  #endif
  #if __BYTE_ORDER == __BIG_ENDIAN
  unsigned int ip_v:4; /* version */
  unsigned int ip_hl:4; /* header length */
  #endif
  u_int8_t ip_tos; /* type of service */
  u_short ip_len; /* total length */
  u_short ip_id; /* identification */
  u_short ip_off; /* fragment offset field */
  #define IP_RF 0x8000 /* reserved fragment flag */
  #define IP_DF 0x4000 /* dont fragment flag */
  #define IP_MF 0x2000 /* more fragments flag */
  #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
  u_int8_t ip_ttl; /* time to live */
  u_int8_t ip_p; /* protocol */
  u_short ip_sum; /* checksum */
  struct in_addr ip_src, ip_dst; /* source and dest address */
  };
  ip_vIP协议的版本号,这里是4,现在IPV6已经出来了。
  ip_hlIP包首部长度,这个值以4字节为单位。IP协议首部的固定长度为20个字节,如果IP包没有选项,那么这个值为5。
  ip_tos服务类型,说明提供的优先权。
  ip_len说明IP数据的长度,以字节为单位。
  ip_id标识这个IP数据包。
  ip_off碎片偏移,这和上面ID一起用来重组碎片的。
  ip_ttl生存时间,每经过一个路由的时候减一,直到为0时被抛弃。
  ip_p协议,表示创建这个IP数据包的高层协议,如TCP、UDP协议.
  ip_sum首部校验和,提供对首部数据的校验。
  ip_src、ip_dst发送者和接收者的IP地址。
  关于IP协议的详细情况,请参考RFC791。
   7.3 ICMP协议
  ICMP是消息控制协议,也处于网络层。在网络上传递IP数据包时,如果发生了错误,那么就会用ICMP协议来报告错误。
  ICMP包的结构如下:
  0 8 16 32
  +--------------+--------------+--------------------------------+
  |   类型   |   代码   |       校验和       |
  +--------------+--------------+--------------------------------+
  |       数据       |        数据        |
  +-----------------------------+--------------------------------+
  ICMP在 中的定义是:
  struct icmphdr
  {
  u_int8_t type; /* message type */
  u_int8_t code; /* type sub-code */
  u_int16_t checksum;
  union
  {
  struct
  {
  u_int16_t id;
  u_int16_t sequence;
  } echo; /* echo datagram */
  u_int32_t gateway; /* gateway address */
  struct
  {
  u_int16_t __unused;
  u_int16_t mtu;
  } frag; /* path mtu discovery */
  } un;
  };
  关于ICMP协议的详细情况可以查看RFC792。
   7.4 UDP协议
  UDP协议是建立在IP协议基础之上的,用在传输层的协议。UDP和IP协议一样是不可靠的数据报服务。
  UDP的头格式为:
  0 16  32
  +-----------------------+------------------------+
  |    UDP源端口    |    UDP目的端口    |
  +-----------------------+------------------------+
  |   UDP数据报长度    |    UDP数据报校验   |
  +-----------------------+------------------------+
  UDP结构在 中的定义为:
  struct udphdr {
  u_int16_t source;
  u_int16_t dest;
  u_int16_t len;
  u_int16_t check;
  };
  关于UDP协议的详细情况,请参考RFC768。
   7.5 TCP
  TCP协议也是建立在IP协议之上的,不过TCP协议是可靠的、按照顺序发送的。TCP的数据结构比前面的结构都要复杂。
  0 4 8 10 16 24 32
  +-------------------------------+---------------------------------+
  |       源端口       |       目的端口       |
  +-------------------------------+---------------------------------+
  |                序列号                 |
  +-----------------------------------------------------------------+
  |                确认号                 |
  +-------+-------------+-+-+-+-+-+---------------------------------+
  |    |     |U|A|P|S|F|                  |
  |首部长度|  保留 |R|C|S|Y|I|        窗口        |
  |    |     |G|K|H|N|N|                  |
  +-------+-------------+-+-+-+-+-+---------------------------------+
  |       校验和       |       紧急指针       |
  +-------------------------------+-----------------+---------------+
  |            选项             |  填充字节  |
  +-------------------------------------------------+---------------+
  TCP的结构在 中定义为:
  struct tcphdr
  {
  u_int16_t source;
  u_int16_t dest;
  u_int32_t seq;
  u_int32_t ack_seq;
  #if __BYTE_ORDER == __LITTLE_ENDIAN
  u_int16_t res1:4;
  u_int16_t doff:4;
  u_int16_t fin:1;
  u_int16_t syn:1;
  u_int16_t rst:1;
  u_int16_t psh:1;
  u_int16_t ack:1;
  u_int16_t urg:1;
  u_int16_t res2:2;
  #elif __BYTE_ORDER == __BIG_ENDIAN
  u_int16_t doff:4;
  u_int16_t res1:4;
  u_int16_t res2:2;
  u_int16_t urg:1;
  u_int16_t ack:1;
  u_int16_t psh:1;
  u_int16_t rst:1;
  u_int16_t syn:1;
  u_int16_t fin:1;
  #endif
  u_int16_t window;
  u_int16_t check;
  u_int16_t urg_prt;
  };
  source发送TCP数据的源端口。
  dest接受TCP数据的目的端口。
  seq标识该TCP所包含的数据字节的开始序列号。
  ack_seq确认序列号,表示接受方下一次接受的数据序列号。
  doff数据首部长度。和IP协议一样,以4字节为单位。一般的时候为5。
  urg如果设置紧急数据指针,则该位为1。
  ack如果确认号正确,那么为1。
  psh如果设置为1,那么接收方收到数据后,立即交给上一层程序。
  rst为1的时候,表示请求重新连接。
  syn为1的时候,表示请求建立连接。
  fin为1的时候,表示亲戚关闭连接。
  window窗口,告诉接收者可以接收的大小。
  check对TCP数据进行较核。
  urg_ptr如果urg=1,那么指出紧急数据对于历史数据开始的序列号的偏移值。
  关于TCP协议的详细情况,请查看RFC793。
   7.6 TCP连接的建立
  TCP协议是一种可靠的连接,为了保证连接的可靠性,TCP的连接要分为几个步骤。我们把这个连接过程称为“三次握手”。
  下面我们从一个实例来分析建立连接的过程。
  第一步客户机向服务器发送一个TCP数据包,表示请求建立连接。为此,客户端将数据包的SYN位设置为1,并且设置序列号seq=1000(我们假设为1000)。
  第二步服务器收到了数据包,并从SYN位为1知道这是一个建立请求的连接,于是服务器也向客户端发送一个TCP数据包。因为是响应客户机的请求,于是服务器设置ACK为1,sak_seq=1001(1000+1)同时设置自己的序列号,seq=2000(我们假设为2000)。
  第三步客户机收到了服务器的TCP,并从ACK为1和ack_seq=1001知道是从服务器来的确认信息,于是客户机也向服务器发送确认信息。客户机设置ACK=1和ack_seq=2001、seq=1001发送给服务器。至此客户端完成连接。
  最后一步服务器受到确认信息,也完成连接。
  通过上面几个步骤,一个TCP连接就建立了。当然在建立过程中可能出现错误,不过TCP协议可以保证自己去处理错误的。
  说一说其中的一种错误。
  听说过DOS吗?(可不是操作系统啊)
  今年春节的时候,美国的五大网站一起受到攻击。攻击者用的就是DOS(拒绝式服务)方式。概括的说一下原理。
  客户机先进行第一个步骤。服务器收到后,进行第二个步骤。按照正常的TCP连接,客户机应该进行第三个步骤。不过攻击者实际上并不进行第三个步骤。因为客户端在进行第一个步骤的时候,修改了自己的IP地址,就是说将一个实际上不存在的IP填充在自己IP数据包的发送者的IP一栏。这样因为服务器发的IP地址没有人接收,所以服务端会收不到第三个步骤的确认信号,这样服务务端会在那边一直等待,直到超时。这样当有大量的客户发出请求后,服务端会有大量等待,直到所有的资源被用光,而不能再接收客户机的请求。这样当正常的用户向服务器发出请求时,由于没有了资源而不能成功。于是就出现了春节时所出现的情况。

本文转自
http://snailium.blog.163.com/blog/static/591757200622522260/
在Internet普及的今天,作为Internet工作基础的TCP/IP协议及其编程已经成了IT人业人员所要具备的基本知识与技能。打开国内外各大知名网站的招聘页面,都可以看到类似于“熟悉TCP/IP协议、掌握socket通讯开发”等字样的要求。本书就是为了满足读者在这方面知识的需求而编写的一本TCP/IP协议与基于TCP/IP编程方面的书籍。 本书有以下几个方面的特点: (1)内容的组织上按照协议原理与协议编程分为上、下篇。上篇主要介绍TCP/IP协议簇中的常用协议,下篇专门介绍网络编程知识与技能。 (2)具体在编写每一节的内容时将原理知识与实用技能融为一体。以方便读者学习。 (3)考虑到TCP/IP协议比较抽象,学习起来有一定的难度,所以全书尽量避免使用晦涩难懂专业术语,而用浅显易懂的语言说明问题,努力将书打造成一本人人都读懂书籍。 (4)初学网络程序设计的人员,往往感到网络程序设计内容多,学习进来比较复杂。针对这一问题,本书在讲解网络程序设计时,根据网络程序固有的特点,先总结了网络程序设计的通用模式,然后再举例说明网络程序的设计,使读者易于入手。 (5)Winsock函数内容多,使用起来比较复杂,针对这一问题,笔者在写作时将常用的Winsock函数分散到各实例中去介绍,然后在最后一章将所有常用的Winsock函数一一作了较为详细说明,并在每个函数后面加入了其应用实例或使用说明。 本书分为上、下两篇内容,上篇内容包含6章,各章主要如下: 第1章:介绍了TCP/IP协议的产生、结构和工作原理,另外本章内容中还简要介绍一一下ISO/OSI RM。 第2章:介绍TCP/IP协议层次结构中网络接口层包含的内容,主要有物理层和数据链路的相关知识。 第3章:介绍TCP/IP协议层次结构中网络层及其相关知识。主要内容有IP数据报格式、IP层的功能、IP地址、ICMP协议、地址转换协议并介绍了IP的最新版本IP v6等。 第4章:介绍TCP/IP协议层次结构中传输层及其相关知识。主要内容有端口的概念、TCP协议和UDP协议协议数据格式、协议原理和TCP协议与UDP协议的比较等内容。 第5章:介绍TCP/IP协议层次结构中应用层及其相关知识。主要内容有应用层常用协议DNS、FTP、Telnet、HTTP、POP和SMTP的格式、工作原理、协议实例等内容。 第6章:简要的介绍了一下TCP/IP协议在Windows和LINUX操作系统下的实现原理TCP/IP协议的二进制代码。 下篇包含以下6章内容: 第7章:介绍了网络程序设计有关的基础知识、一个网络程序入门实例和Winsock中编写网络程序常用的建立连接、传输数据、关闭连接等有关的函数。 第8章:介绍了TCP程序设计流程、基于C/C++的TCP程序设计实例和基于Java技术的TCP程序设计实例。 第9章:介绍了UDP程序设计流程、基于C/C++的UDP程序设计实例和基于Java技术的UDP程序设计实例。 第10章:介绍了使用MFC中提供的有关类进行网络程序设计知识。 第11章:介绍了Winsock API中各函数的功能,并举例说明了些函数的使用方法。 本书在编写过程中得到了邮电出版和刘博等编辑的大力支持和帮助,在此表示感谢。由于作者水平有限,错漏之处在所难免,欢迎广大读者批评指正和提出宝贵的意见,可发邮件到。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值