1、tcpip协议栈开发竭诚为您提供优质文档/双击可除tcpip协议栈开发篇一:什么是tcpip协议栈?栈是什么意思?什么是tcp/ip协议栈?栈是什么意思?tcp/ip协议叫做传输控制/网际协议,它是internet国际互联网络的基础。tcp/ip是网络中使用的基本的通信协议。虽然从名字上看tcp/ip包括两个协议,传输控制协议(tcp)和网际协议(ip),但tcp/ip实际上是一组协议,它包括上百个各种功能的协议,如:远程登录、文件传输和电子邮件等,而tcp协议和ip协议是保证数据完整传输的两个基本的重要协议。通常说tcp/ip是internet协议族,而不单单是tcp和ip。tcp/ip协议
2、的基本传输单位是数据包(datagram),tcp协议负责把数据分成若干个数据包,并给每个数据包加上包头(就像给一封信加上信封),包头上有相应的编号,以保证在数据接收端能将数据还原为原来的格式,ip协议在每个包头上再加上接收端主机地址,这样数据找到自己要去的地方,如果传输过程中出现数据丢失、数据失真等情况,tcp协议会自动要求数据重新传输,并重新组包。总之,ip协议保证数据的传输,tcp协议保证数据传输的质量。tcp/ip协议数据的传输基于tcp/ip协议的四层结构:应用层、传输层、网络层、接口层,数据在传输时每通过一层就要在数据上加个包头,其中的数据供接收端同一层协议使用,而在接收端,每经过
3、一层要把用过的包头去掉,这样来保证传输数据的格式完全一致。tcp/ip协议介绍tcp/ip的通讯协议这部分简要介绍一下tcp/ip的内部结构,为讨论与互联网有关的安全问题打下基础。tcp/ip协议组之所以流行,部分原因是因为它可以用在各种各样的信道和底层协议(例如t1和x.25、以太网以及Rs-232串行接口)之上。确切地说,tcp/ip协议是一组包括tcp协议和ip协议,udp(userdatagramprotocol)协议、icmp(internetcontrolmessageprotocol)协议和其他一些协议的协议组。tcp/ip整体构架概述tcp/ip协议并不完全符合osi的七层参考
4、模型。传统的开放式系统互连参考模型,是一种通信协议的7层抽象的参考模型,其中每一层执行某一特定任务。该模型的目的是使各种硬件在相同的层次上相互通信。这7层是:物理层、数据链路层、网路层、传输层、话路层、表示层和应用层。而tcp/ip通讯协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。这4层分别为:应用层:应用程序间沟通的层,如简单电子邮件传输(smtp)、文件传输协议(Ftp)、网络远程访问协议(telnet)等。传输层:在此层中,它提供了节点间的数据传送服务,如传输控制协议(tcp)、用户数据报协议(udp)等,tcp和udp给数据包加入传输数据并把它传输到下一
5、层中,这一层负责传送数据,并且确定数据已被送达并接收。互连网络层:负责提供基本的数据封包传送功能,让每一块数据包都能够到达目的主机(但不检查是否被正确接收),如网际协议(ip)。网络接口层:对实际的网络媒体的管理,定义如何使用实际网络(如ethernet、serialline等)来传送数据。tcp/ip中的协议以下简单介绍tcp/ip中的协议都具备什么样的功能,都是如何工作的:1ip网际协议ip是tcp/ip的心脏,也是网络层中最重要的协议。ip层接收由更低层(网络接口层例如以太网设备驱动程序)发来的数据包,并把该数据包发送到更高层-tcp或udp层;相反,ip层也把从tcp或udp层接收来的
6、数据包传送到更低层。ip数据包是不可靠的,因为ip并没有做任何事情来确认数据包是按顺序发送的或者没有被破坏。ip数据包中含有发送它的主机的地址(源地址)和接收它的主机的地址(目的地址)。高层的tcp和udp服务在接收数据包时,通常假设包中的源地址是有效的。也可以这样说,ip地址形成了许多服务的认证基础,这些服务相信数据包是从一个有效的主机发送来的。ip确认包含一个选项,叫作ipsourcerouting,可以用来指定一条源地址和目的地址之间的直接路径。对于一些tcp和udp的服务来说,使用了该选项的ip包好象是从路径上的最后一个系统传递过来的,而不是来自于它的真实地点。这个选项是为了测试而存在
7、的,说明了它可以被用来欺骗系统来进行平常是被禁止的连接。那么,许多依靠ip源地址做确认的服务将产生问题并且会被非法入侵。2.tcp如果ip数据包中有已经封好的tcp数据包,那么ip将把它们向上传送到tcp层。tcp将包排序并进行错误检查,同时实现虚电路间的连接。tcp数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。tcp将它的信息送到更高层的应用程序,例如telnet的服务程序和客户程序。应用程序轮流将信息送回tcp层,tcp层便将它们向下传送到ip层,设备驱动程序和物理介质,最后到接收方。面向连接的服务(例如telnet、Ftp、rlogin、xwindows
8、和smtp)需要高度的可靠性,所以它们使用了tcp。dns在某些情况下使用tcp(发送和接收域名数据库),但使用udp传送有关单个主机的信息。3.udpudp与tcp位于同一层,但对于数据包的顺序错误或重发。因此,udp不被应用于那些使用虚电路的面向连接的服务,udp主要用于那些面向查询-应答的服务,例如nFs。相对于Ftp或telnet,这些服务需要交换的信息量较小。使用udp的服务包括ntp(网落时间协议)和dns(dns也使用tcp)。欺骗udp包比欺骗tcp包更容易,因为udp没有建立初始化连接(也可以称为握手)(因为在两个系统间没有虚电路),也就是说,与udp相关的服务面临着更大的危
9、险。4.icmpicmp与ip位于同一层,它被用来传送ip的的控制信息。它主要是用来提供有关通向目的地址的路径信息。icmp的Redirect信息通知主机通向其他系统的更准确的路径,而ueachable信息则指出路径有问题。另外,如果路径不可用了,icmp可以使tcp连接体面地终止。ping是最常用的基于icmp的服务。5.tcp和udp的端口结构tcp和udp服务通常有一个客户/服务器的关系,例如,一个telnet服务进程开始在系统上处于空闲状态,等待着连接。用户使用telnet客户程序与服务进程建立一个连接。客户程序向服务进程写入信息,服务进程读出信息并发出响应,客户程序读出响应并向用户报
10、告。因而,这个连接是双工的,可以用来进行读写。两个系统间的多重telnet连接是如何相互确认并协调一致呢?tcp或udp连接唯一地使用每个信息中的如下四项进行确认:源ip地址发送包的ip地址。目的ip地址接收包的ip地址。源端口源系统上的连接的端口。目的端口目的系统上的连接的端口。端口是一个软件结构,被客户程序或服务进程用来发送和接收信息。一个端口对应一个16比特的数。服务进程通常使用一个固定的端口,例如,smtp使用25、xwindows使用6000。这些端口号是广为人知的,因为在建立与特定的主机或服务的连接时,需要这些地址和目的地址进行通讯。篇二:linuxtcpip协议栈分析sk_buf
11、f结构可能是linux网络代码中最重要的数据结构,它表示接收或发送数据包的包头信息。它在中定义,并包含很多成员变量供网络代码中的各子系统使用。这个结构在linux内核的发展过程中改动过很多次,或者是增加新的选项,或者是重新组织已存在的成员变量以使得成员变量的布局更加清晰。它的成员变量可以大致分为以下几类:layout布局general通用Feature-specific功能相关managementfunctions管理函数这个结构被不同的网络层(mac或者其他二层链路协议,三层的ip,四层的tcp或udp等)使用,并且其中的成员变量在结构从一层向另一层传递时改变。l4向l3传递前会添加一个l4
12、的头部,同样,l3向l2传递前,会添加一个l3的头部。添加头部比在不同层之间拷贝数据的效率更高。由于在缓冲区的头部添加数据意味着要修改指向缓冲区的指针,这是个复杂的操作,所以内核提供了一个函数skb_reserve(在后面的章节中描述)来完成这个功能。协议栈中的每一层在往下一层传递缓冲区前,第一件事就是调用skb_reserve在缓冲区的头部给协议头预留一定的空间。skb_reserve同样被设备驱动使用来对齐接收到包的包头。如果缓冲区向上层协议传递,旧的协议层的头部信息就没什么用了。例如,l2的头部只有在网络驱动处理l2的协议时有用,l3是不会关心它的信息的。但是,内核并没有把l2的头部从缓
13、冲区中删除,而是把有效荷载的指针指向l3的头部,这样做,可以节省cpu时间。1.网络参数和内核数据结构就像你在浏览tcp/ip规范或者配置内核时所看到的一样,网络代码提供了很多有用的功能,但是这些功能并不是必须的,比如说,防火墙,多播,还有其他一些功能。大部分的功能都需要在内核数据结构中添加自己的成员变量。因此,sk_buff里面包含了很多像#ifdef这样的预编译指令。例如,在sk_buff结构的最后,你可以找到:structsk_buff.#ifdefconFig_net_sched_u32tc_index;#ifdefconFig_net_cls_act_u32tc_verd;_u32t
14、c_classid;#endif#endif它表明,tc_index只有在编译时定义了conFig_net_sched符号才有效。这个符号可以通过选择特定的编译选项来定义(例如:devicedriversnetworkingsupportnetworkingoptionsqosand/orfairqueueing)。这些编译选项可以由管理员通过makeconfig来选择,或者通过一些自动安装工具来选择。前面的例子有两个嵌套的选项:conFig_net_cls_act(包分类器)只有在选择支持“qosand/orfairqueueing”时才能生效。顺便提一下,qos选项不能被编译成内核模块。原
15、因就是,内核编译之后,由某个选项所控制的数据结构是不能动态变化的。一般来说,如果某个选项会修改内核数据结构(比如说,在sk_buff里面增加一个项tc_index),那么,包含这个选项的组件就不能被编译成内核模块。你可能经常需要查找是哪个makeconfig编译选项或者变种定义了某个#ifdef标记,以便理解内核中包含的某段代码。在2.6内核中,最快的,查找它们之间关联关系的方法,就是查找分布在内核源代码树中的kconfig文件中是否定义了相应的符号(每个目录都有一个这样的文件)。在2.4内核中,你需要查看documentation/configure.help文件。2.layoutField
16、s有些sk_buff成员变量的作用是方便查找或者是连接数据结构本身。内核可以把sk_buff组织成一个双向链表。当然,这个链表的结构要比常见的双向链表的结构复杂一点。就像任何一个双向链表一样,sk_buff中有两个指针next和prev,其中,next指向下一个节点,而prev指向上一个节点。但是,这个链表还有另一个需求:每个sk_buff结构都必须能够很快找到链表头节点。为了满足这个需求,在第一个节点前面会插入另一个结构sk_buff_head,这是一个辅助节点,它的定义如下:structsk_buff_head/*thesetwomembersmustbefirst.*/structsk_
17、buff*next;structsk_buff*prev;_u32qlen;spinlock_tlock;qlen代表链表元素的个数。lock用于防止对链表的并发访问。sk_buff和sk_buff_head的前两个元素是一样的:next和prev指针。这使得它们可以放到同一个链表中,尽管sk_buff_head要比sk_buff小得多。另外,相同的函数可以同样应用于sk_buff和sk_buff_head。为了使这个数据结构更灵活,每个sk_buff结构都包含一个指向sk_buff_head的指针。这个指针的名字是list。图1会帮助你理解它们之间的关系。Figure1.listofsk_b
18、uffelements其他有趣的成员变量如下:structsock*sk这是一个指向拥有这个sk_buff的sock结构的指针。这个指针在网络包由本机发出或者由本机进程接收时有效,因为插口相关的信息被l4(tcp或udp)或者用户空间程序使用。如果sk_buff只在转发中使用(这意味着,源地址和目的地址都不是本机地址),这个指针是null。unsignedintlen这是缓冲区中数据部分的长度。它包括主缓冲区中的数据长度(data指针指向它)和分片中的数据长度。它的值在缓冲区从一个层向另一个层传递时改变,因为往上层传递,旧的头部就没有用了,而往下层传递,需要添加本层的头部。len同样包含了协议
19、头的长度。unsignedintdata_len和len不同,data_len只计算分片中数据的长度。unsignedintmac_len这是mac头的长度。atomic_tusers这是一个引用计数,用于计算有多少实体引用了这个sk_buff缓冲区。它的主要用途是防止释放sk_buff后,还有其他实体引用这个sk_buff。因此,每个引用这个缓冲区的实体都必须在适当的时候增加或减小这个变量。这个计数器只保护sk_buff结构本身,而缓冲区的数据部分由类似的计数器(dataref)来保护.有时可以用atomic_inc和atomic_dec函数来直接增加或减小users,但是,通常还是使用函数
20、skb_get和kfree_skb来操作这个变量。unsignedinttruesize这是缓冲区的总长度,包括sk_buff结构和数据部分。如果申请一个len字节的缓冲区,alloc_skb函数会把它初始化成len+sizeof(sk_buff)。structsk_buff*alloc_skb(unsignedintsize,intgfp_mask).skb-truesize=size+sizeof(structsk_buff);.当skb-len变化时,这个变量也会变化。unsignedchar*headunsignedchar*endunsignedchar*dataunsignedch
21、ar*tail它们表示缓冲区和数据部分的边界。在每一层申请缓冲区时,它会分配比协议头或协议数据大的空间。head和end指向缓冲区的头部和尾部,而data和tail指向实际数据的头部和尾部,参见图2。每一层会在head和data之间填充协议头,或者在tail和end之间添加新的协议数据。图2中右边数据部分会在尾部包含一个附加的头部。Figure2.head/endversusdata/tailpointersvoid(*destructor)(.)这个函数指针可以初始化成一个在缓冲区释放时完成某些动作的函数。如果缓冲区不属于一个socket,这个函数指针通常是不会被赋值的。如果缓冲区属于一个s
22、ocket,这个函数指针会被赋值为sock_rfree或sock_wfree(分别由skb_set_owner_r或skb_set_owner_w函数初始化)。这两个sock_xxx函数用于更新socket的队列中的内存容量。3.generalFields本节描述sk_buff的主要成员变量,这些成员变量与特定的内核功能无关:structtimevalstamp这个变量只对接收到的包有意义。它代表包接收时的时间戳,或者有时代表包准备发出时的时间戳。它在netif_rx里面由函数net_timestamp设置,而netif_rx是设备驱动收到一个包后调用的函数。structnet_device*
23、dev这个变量的类型是net_device,net_device它代表一个网络设备。dev的作用与这个包是准备发出的包还是刚接收的包有关。当收到一个包时,设备驱动会把sk_buff的dev指针指向收到这个包的设备的数据结构,就像下面的vortex_rx里的一段代码所做的一样,这个函数属于3c59x系列以太网卡驱动,用于接收一个帧。(drivers/net/3c59x.c):staticintvortex_rx(structnet_device*dev).skb-dev=dev;.skb-protocol=eth_type_trans(skb,dev);netif_rx(skb);/*passt
24、hepackettothehigherlayer*/.当一个包被发送时,这个变量代表将要发送这个包的设备。在发送网络包时设置这个值的代码要比接收网络包时设置这个值的代码复杂。有些网络功能可以把多个网络设备组成一个虚拟的网络设备(也就是说,这些设备没有和物理设备直接关联),并由一个虚拟网络设备驱动管理。当虚拟设备被使用时,dev指针指向虚拟设备的net_device结构。而虚拟设备驱动会在一组设备中选择一个设备并把dev指针修改为这个设备的net_device结构。因此,在某些情况下,指向传输设备的指针会在包处理过程中被改变。structnet_device*input_dev这是收到包的网络设
25、备的指针。如果包是本地生成的,这个值为null。对以太网设备来说,这个值由eth_type_trans初始化,它主要被流量控制代码使用。structnet_device*real_dev这个变量只对虚拟设备有意义,它代表与虚拟设备关联的真实设备。例如,bonding和Vlan设备都使用它来指向收到包的真实设备。篇三:tcpip协议编程tcp/ip协议编程1.1实验目的:1、掌握基于tcp/ip协议进行远程通讯的原理2、掌握sockets网络程序设计的原理和方法3、理解面向连接服务、面向无连接的特点1.2实验任务1学会winsock网络编程基础2winsock控件的属性和方法13实验环境wind
26、ows98或windows2000操作系统,编译环境任选。14实验方法一、实验原理(一)tcp/ip的特点和sockettcp/ip是网络上广泛应用的协议,其中ip是网络层的协议,它是无连接的;tcp是传输层的协议,它是面向连接的。在实际系统中,tcp/ip通常在操作系统内核中实现,用户所能感受到的和可以用来进行网络程序开发的是操作系统提供的网络编程界面。在tcp/ip网络环境下,网络编程界面称为套接字(socket)(见图1)。图1、tcp/ip协议核心与应用程序关系图图1中的应用程序1和2可以是位于不同主机上的2个进程,他们的作用方式是客户/服务器模式。1、sockets编程原理(1)so
27、ckets编程中的主要概念协议、地址、端口:在sockets编程中,传输层的协议既可以是tcp,也可以是udp。sockets是用于网间进程通讯的,因此在标识上要进行网间进程标识。地址是标识主机的,在sockets编程中通常指ip地址;而端口标识通信的进程,它可以是1-65535间的任何一个数字,其中1-255保留给特定的服务、256-1023保留给其它的一般服务(如路由函数)、1024-4999可以被任意的客户机端口使用、5000-65535可以被任意的服务器端口使用。地址+端口就实现了网间进程标识。(协议、本地地址、本地端口号、远程地址、远程端口号)是一组五元相关。面向连结、无连接、soc
28、ket类型:传输层中的tcp协议是面向连接的,udp协议是无连接的,因此socket主要有两种类型:流套接字用于tcp/ip编程,提供面向连接的服务;数据报套接字用于udp/ip编程,提供无连接的服务。网络字节顺序:不同的计算机存放多字节值的顺序不同,为保证数据的正确性,在网络协议中必须指定网络字节顺序。tcp/ip协议使用16位整数和32位整数的高位先存格式。在编程中,调用htons()和htonl()函数来转换端口(短整型数值)和地址(长整型数值)参数的字节顺序(2)sockets编程原理创建套接字:用socket()来创建套接字。指定本地地址:用bind()来指定本地地址。侦听连接:面向
29、连接的服务中,服务器套接字在socket()和bind()后,就要调用listen()来侦听客户机的请求。建立套接字连接:面向连接的服务中,客户机在socket()和bind()之后,要调用connect()来向服务器请求连接,服务器在侦听到客户机的请求后,要调用accept()来接受连接。数据传输:当一个连接建立以后,就可以传输数据了。在传输数据时,用到send()和recv()。输入/输出多路复用:用select()函数指定你想等待数据的套接字,当数据被套接字接收到以后,select()返回,并确定在输入队列中哪个套接字在等待数据,然后,就可以接收数据。关闭套接字:用closesocket
30、()函数关闭套接字,并释放分配给该套接字的资源。2、使用已封装好的类进行windowssockets编程以上所提到的winsock编程的方法和函数是标准sockets调用和winsockapi所提供的,在windows环境下使用任何编程语言、开发环境都可以实现。现在,很多开发环境都提供了已经封装好的用于windowssockets编程的类,这些现成的类使得winsock的程序开发更方便、快速。图2演示了面向连接的流套接字的工作过程;图3演示了无连接的数据报。二实验步骤使用tcp/ip协议编写一个聊天程序。本例使用udp协议建立一个“聊天”程序。所谓“聊天”是指两个程序能够发送数据给对方,在此两个程序之间是平等的、处于同一地位,没有服务器和客户的区别。另外,udp程序不需建立显式的连接,所以在程序编写上比使用tcp方式简单。建立“聊天a”程序的步骤如下:(1)打开Visualbasic6.0中文版,创建标准工程。在工具箱上单击右键,在弹出的菜单中选择“部件”菜单项,在弹出的“部件”对话框中,选中“miscrosoftwindowscommonontrols6.0”和”microsoftwinsockcontrol6.
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1