TCP协议实验
TCP协议实验

TCP协议实验协议名称:TCP协议实验协议一、背景介绍TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输层协议,广泛应用于互联网中。
为了验证TCP协议的可靠性和性能,本实验旨在设计并实现一个简单的TCP协议实验。
二、实验目的1. 理解TCP协议的基本原理和工作机制;2. 掌握TCP协议的可靠性和流量控制机制;3. 验证TCP协议在不同网络环境下的性能。
三、实验内容1. 搭建实验环境a) 准备两台计算机,分别作为客户端和服务器;b) 在两台计算机上安装TCP协议实验软件。
2. 实验步骤a) 启动服务器端软件,并设置监听端口;b) 启动客户端软件,输入服务器端IP地址和监听端口;c) 客户端向服务器端发送连接请求;d) 服务器端接受连接请求,并建立TCP连接;e) 客户端和服务器端之间进行数据传输;f) 客户端发送断开连接请求,服务器端断开连接。
3. 实验参数设置a) 数据传输速率:设置不同的传输速率,如100Mbps、1Gbps等;b) 数据包大小:设置不同的数据包大小,如1000字节、1500字节等;c) 网络延迟:模拟不同的网络延迟,如10ms、50ms等;d) 丢包率:模拟不同的丢包率,如0%、5%等。
4. 实验数据收集a) 记录实验过程中的数据传输情况,包括传输速率、数据包大小、延迟和丢包率;b) 统计数据传输成功率、平均延迟和平均吞吐量等指标。
5. 实验结果分析a) 分析不同参数对TCP协议性能的影响;b) 比较实验结果与理论预期的差异,分析原因。
四、实验安全措施1. 确保实验环境的安全性,防止非法入侵;2. 遵守计算机网络使用规定,不进行非法操作;3. 注意数据传输过程中的隐私保护。
五、实验注意事项1. 操作过程中保持实验环境的稳定性,避免其他网络活动对实验结果的影响;2. 注意实验过程中的数据采集和记录,确保数据的准确性;3. 如遇到异常情况,及时记录并排查故障原因。
TCP协议实验

TCP协议实验协议名称:TCP协议实验协议1. 引言TCP(传输控制协议)是一种面向连接的、可靠的传输层协议,广泛应用于互联网通信中。
本实验协议旨在通过实践操作,深入理解TCP协议的工作原理、特性和性能。
2. 实验目的本实验旨在帮助学生通过实际操作,加深对TCP协议的理解,包括如下方面:- 学习TCP协议的基本工作原理;- 掌握TCP协议的连接建立、数据传输和连接释放过程;- 熟悉TCP协议的可靠性机制和流量控制;- 了解TCP协议的拥塞控制机制和性能优化策略。
3. 实验环境- 操作系统:Windows 10 / macOS / Linux- 软件工具:Wireshark(用于网络数据包的捕获和分析)4. 实验任务本实验包括以下任务:任务1:TCP连接建立和释放- 步骤1:准备两台计算机,并确保网络连接正常。
- 步骤2:使用Wireshark捕获计算机A和计算机B之间的TCP连接建立和释放过程的数据包。
- 步骤3:分析捕获到的数据包,了解TCP连接建立和释放的过程、相关字段的含义和作用。
任务2:TCP数据传输和可靠性机制- 步骤1:准备两台计算机,并确保网络连接正常。
- 步骤2:使用Wireshark捕获计算机A向计算机B发送数据的过程中的数据包。
- 步骤3:分析捕获到的数据包,了解TCP的数据传输机制、序号和确认号的作用、超时重传机制等。
任务3:TCP流量控制和拥塞控制- 步骤1:准备两台计算机,并确保网络连接正常。
- 步骤2:使用Wireshark捕获计算机A向计算机B发送大量数据时的数据包。
- 步骤3:分析捕获到的数据包,了解TCP的流量控制机制、滑动窗口的作用以及拥塞控制的原理。
任务4:TCP性能优化- 步骤1:准备两台计算机,并确保网络连接正常。
- 步骤2:使用Wireshark捕获计算机A和计算机B之间进行TCP通信时的数据包。
- 步骤3:分析捕获到的数据包,了解TCP的性能优化策略,如快速重传、快速恢复、拥塞避免等。
实验7 传输控制协议(TCP)

院系:计算机学院实验课程:计算机网络与因特网实验项目:用户数据报协议(UDP)指导老师:开课时间:2011 ~ 2012年度第 2学期专业:网络工程班级:学生:学号:一、实验项目名称传输控制协议(TCP)二、实验目的1、掌握TCP 协议的报文形式;2、掌握TCP 连接的建立和释放过程;3、掌握TCP 数据传输中编号与确认的过程;4、掌握TCP协议校验和的计算方法;5、理解TCP 重传机制。
三、实验主要硬件软件环境PC机,Windows操作系统。
四、实验内容及步骤练习1 查看TCP连接的建立和释放各主机打开工具区的“拓扑验证工具”,选择相应的网络结构,配置网卡后,进行拓扑验证,如果通过拓扑验证,关闭工具继续进行实验,如果没有通过,请检查网络连接。
本练习将主机A 和B 作为一组,主机C 和D 作为一组,主机E 和F 作为一组。
现仅以主机 A 和 B 为例,其他组参考主机A、B的操作。
1. 主机B启动协议分析器捕获数据,并设置过滤条件(提取TCP协议)。
2. 主机A启动TCP工具连接主机B。
(1)主机A启动实验平台工具栏中的“地址本工具”。
点击[主机扫描]按钮获取组内主机信息,选中主机B点击[端口扫描]按钮获取主机B的TCP端口列表。
(2)主机A启动实验平台工具栏中的“TCP工具”。
选中“客户端”单选框,在“地址”文本框中填入主机B的IP地址,在“端口”文本框中填入主机B的一个TCP 端口,点击[连接]按钮进行连接。
●TCP连接建立时,前两个报文的首部都有一个“最大字段长度”字段,它的值是多少?作用是什么?结合IEEE802.3协议规定的以太网最大帧长度分析此数据是怎样得出的。
答:1460;由发送端指定,表明了能在网络上传输的最大的段尺寸;maximum segment size = MTU –20(IP首部)-20(TCP首部)。
4. 主机A断开与主机B的TCP连接。
5. 察看主机B捕获的数据,填写下表。
tcp实验报告

tcp实验报告TCP实验报告一、实验目的TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议,它在互联网通信中扮演着重要的角色。
本实验旨在通过实际操作和观察,深入理解TCP协议的工作原理和特点。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.93. 实验工具:Wireshark三、实验步骤与结果1. 建立TCP连接通过Python的socket库,我们可以轻松地创建TCP连接。
在本实验中,我们编写了一个简单的服务器端和客户端程序,通过本地主机进行通信。
2. 数据传输与流量控制在TCP连接建立后,我们进行了数据的传输实验。
首先,我们发送了一个较小的数据包,观察到数据包的传输过程中,TCP协议会自动进行流量控制,确保数据的可靠传输。
接着,我们发送了一个较大的数据包,发现TCP会将大数据包拆分成多个小数据包进行传输,并在接收端进行重组。
3. 拥塞控制为了模拟网络拥塞的情况,我们在实验中人为地降低了网络带宽。
通过Wireshark抓包分析,我们观察到TCP协议在发现网络拥塞时,会自动减少发送速率,以避免网络的过载。
同时,我们还注意到TCP协议会根据网络的状况动态调整拥塞窗口的大小,以提高网络的利用率。
4. 可靠性与重传机制为了测试TCP协议的可靠性,我们在实验中故意模拟了数据包丢失的情况。
通过Wireshark的分析,我们发现当发送端未收到确认消息时,会自动触发重传机制,确保数据的可靠传输。
同时,TCP还会根据超时时间的动态调整,以适应不同网络环境下的传输速度。
五、实验总结通过本次实验,我们深入了解了TCP协议的工作原理和特点。
TCP作为一种可靠的传输协议,在互联网通信中发挥着重要的作用。
它通过流量控制、拥塞控制和重传机制等手段,确保了数据的可靠传输,并适应了不同网络环境的变化。
在今后的学习和实践中,我们将进一步深入研究TCP协议的细节,并结合实际应用场景,优化网络通信的性能和可靠性。
TCP协议实验

TCP协议实验协议名称:TCP协议实验协议协议编号:[编号]生效日期:[日期]1. 引言本协议旨在规范和指导TCP协议实验的相关操作和流程,确保实验的顺利进行并获取准确的实验结果。
本协议适用于所有参与TCP协议实验的实验人员。
2. 实验目的本实验旨在深入理解TCP协议的工作原理,掌握TCP协议的基本操作和功能,并通过实验验证TCP协议的可靠性和效率。
3. 实验要求3.1 实验设备参与实验的人员需具备以下设备:- 一台计算机- 安装有TCP/IP协议栈的操作系统- 网络连接设备(例如以太网卡)3.2 实验环境实验环境应满足以下要求:- 稳定的网络连接- 适当的网络带宽和延迟- 实验所需的软件和工具3.3 实验内容实验人员应按照以下步骤进行实验:1. 准备实验环境:确保实验设备和网络环境符合要求。
2. 实验准备:安装和配置实验所需的软件和工具。
3. 实验设计:根据实验目的设计合适的实验方案。
4. 实验执行:按照实验方案进行实验操作。
5. 数据收集:记录实验过程中的数据和结果。
6. 数据分析:对实验数据进行分析和评估。
7. 结果总结:总结实验结果并得出结论。
4. 实验步骤4.1 准备实验环境确保实验设备和网络环境符合要求,包括:- 确保计算机正常工作,操作系统安装完好。
- 确保网络连接设备正常工作,网络连接稳定。
4.2 实验准备安装和配置实验所需的软件和工具,包括:- 安装TCP/IP协议栈。
- 安装网络抓包工具,用于捕获和分析网络数据包。
4.3 实验设计根据实验目的设计合适的实验方案,包括:- 设定实验的网络拓扑结构,确定实验中的发送方和接收方。
- 设定实验中的数据传输量和传输速率。
- 设定实验中的网络延迟和丢包率。
4.4 实验执行按照实验方案进行实验操作,包括:- 启动发送方和接收方的程序。
- 发送方向接收方发送数据。
- 接收方接收数据并发送确认。
- 发送方接收确认并继续发送数据。
4.5 数据收集记录实验过程中的数据和结果,包括:- 捕获和保存实验中的网络数据包。
tcp实验总结

tcp实验总结摘要:1.TCP协议简介2.TCP实验目的与过程3.TCP实验结果与分析4.TCP协议的优点与不足5.总结与建议正文:一、TCP协议简介TCP(Transmission Control Protocol,传输控制协议)是一种面向连接、可靠、基于字节流的传输层通信协议。
它与IP协议共同构成了TCP/IP协议族,是互联网中最常用的协议之一。
TCP协议通过三次握手建立连接,保证数据传输的可靠性,具有错误检测和纠正功能。
二、TCP实验目的与过程本次TCP实验旨在通过实际操作,了解TCP协议的工作原理,掌握TCP 连接的建立、数据传输和断开过程,以及分析TCP协议在实际应用中的性能表现。
实验过程如下:1.搭建TCP服务器和客户端2.实现TCP客户端与服务器的通信3.观察TCP连接的建立与断开4.分析TCP协议的传输性能三、TCP实验结果与分析实验结果显示,TCP协议能够实现可靠的数据传输。
通过对TCP连接的建立、数据传输和断开过程的观察,发现TCP协议具有以下特点:1.TCP连接建立:通过三次握手,客户端与服务器确认对方的存在,并为后续数据传输做好准备。
2.数据传输:TCP协议采用字节流的方式发送数据,保证了数据的顺序和完整性。
3.TCP断开:通过四次挥手,双方确认对方已接收完毕数据,并依次关闭连接。
四、TCP协议的优点与不足优点:1.面向连接,确保数据传输的可靠性2.错误检测和纠正功能,保证数据完整性3.流量控制与拥塞控制,提高网络资源利用率不足:1.相对复杂的实现,占用较多资源2.传输延迟较高,不适合实时应用3.依赖IP协议,不能单独使用五、总结与建议通过TCP实验,我们对TCP协议有了更深入的了解。
在实际应用中,应根据需求选择合适的协议,充分发挥TCP协议的优点,避免其不足。
TCP协议实验

TCP协议实验协议名称:TCP协议实验协议协议目的:本协议旨在规定TCP协议实验的具体步骤和要求,确保实验过程的准确性和可重复性,以提高学生对TCP协议的理解和实践能力。
实验内容:1. 实验目标:1.1 理解TCP协议的工作原理和基本概念;1.2 掌握TCP协议的连接建立和断开过程;1.3 熟悉TCP协议的数据传输机制;1.4 学会使用网络调试工具分析TCP连接过程。
2. 实验环境:2.1 操作系统:任意支持TCP协议的操作系统;2.2 网络环境:可以使用本地环回地址或局域网环境。
3. 实验工具:3.1 Wireshark:用于抓包和分析网络数据;3.2 Telnet:用于模拟TCP连接。
4. 实验步骤:此处将详细描述TCP协议实验的步骤,以确保实验的准确性和可重复性。
4.1 实验前准备:4.1.1 确保实验所需的操作系统和网络环境已准备就绪;4.1.2 安装并配置Wireshark和Telnet工具。
4.2 实验步骤:4.2.1 打开Wireshark工具,开始抓包;4.2.2 打开命令行界面,输入telnet命令,连接到目标主机;4.2.3 在Telnet会话中执行TCP连接建立过程;4.2.4 在Wireshark中分析抓包数据,观察TCP连接建立过程;4.2.5 在Telnet会话中执行数据传输过程;4.2.6 在Wireshark中分析抓包数据,观察TCP数据传输过程;4.2.7 执行TCP连接断开过程;4.2.8 在Wireshark中分析抓包数据,观察TCP连接断开过程。
4.3 实验记录:4.3.1 在实验过程中记录每个步骤的操作和观察结果;4.3.2 记录Wireshark抓包数据的关键信息,如源IP地址、目标IP地址、端口号等。
4.4 实验分析:4.4.1 根据实验记录和Wireshark抓包数据,分析TCP连接建立和断开的细节过程;4.4.2 分析TCP数据传输的可靠性和效率。
TCP协议实验

TCP协议实验协议名称:TCP协议实验协议1. 引言本协议旨在规定TCP协议实验的相关内容和要求,以确保实验的顺利进行。
本协议适合于所有参预TCP协议实验的实验人员。
2. 实验目的本实验旨在通过实际操作和观察,加深对TCP协议的理解,掌握TCP连接建立、数据传输和连接释放的过程,以及相关的控制机制。
3. 实验环境和工具3.1 实验环境- 操作系统:Windows/Linux/OS X等- 网络环境:局域网或者互联网3.2 实验工具- TCP/IP协议分析工具:Wireshark、tcpdump等- 编程语言:C、Python等- 开辟环境:Visual Studio、Eclipse等4. 实验内容4.1 实验前准备- 安装和配置实验环境和工具- 了解TCP协议的基本原理和工作机制4.2 实验步骤1. TCP连接建立实验- 实验目标:观察TCP三次握手过程- 实验步骤:a) 实验人员A作为客户端,实验人员B作为服务器端b) A向B发送SYN包c) B收到SYN包后,向A发送SYN+ACK包d) A收到SYN+ACK包后,向B发送ACK包e) TCP连接建立成功- 实验要求:记录并分析每一个步骤中的数据包,包括源IP地址、目标IP 地址、源端口号、目标端口号等信息2. 数据传输实验- 实验目标:观察TCP数据传输过程- 实验步骤:a) A向B发送数据包b) B收到数据包后,向A发送ACK包c) A收到ACK包后,继续发送数据包d) 重复b)和c)直到数据传输完成- 实验要求:记录并分析每一个步骤中的数据包,包括数据内容、序列号、确认号等信息3. 连接释放实验- 实验目标:观察TCP四次挥手过程- 实验步骤:a) A向B发送FIN包b) B收到FIN包后,向A发送ACK包c) B向A发送FIN包d) A收到FIN包后,向B发送ACK包e) TCP连接释放成功- 实验要求:记录并分析每一个步骤中的数据包,包括源IP地址、目标IP地址、源端口号、目标端口号等信息4. 其他实验(可选)- 实验人员可以根据需要进行其他与TCP协议相关的实验,如拥塞控制、流量控制等5. 实验要求和评估5.1 实验要求- 实验人员需按照实验步骤进行实验操作,并记录相关数据包信息- 实验人员需理解和分析实验结果,并撰写实验报告5.2 实验评估- 实验报告将作为评估实验成果的依据,评估内容包括实验步骤的正确性、数据包信息的准确性和分析的深度等6. 安全注意事项在进行实验过程中,实验人员需遵守以下安全注意事项:- 不得进行未经授权的入侵行为- 不得发送恶意代码或者攻击性数据包- 不得干扰其他实验人员的实验过程- 不得泄露实验数据和结果7. 实验报告实验人员需按照指定格式撰写实验报告,包括实验目的、实验步骤、实验结果和分析等内容。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
网络课第四次上机实验报告------TCP协议实验实验内容实验内容主要包括:设计保存TCP 连接相关信息的数据结构(TCB);TCP 协议的接收处理和封装发送;TCP 协议提供的Socket 函数接口。
实验过程设计保存TCP 连接相关信息的数据结构(TCB)用数据结构TCB为每一个TCP连接维护socketfd,srcAddr,dstAddr, srcPort, dstPort, seq, ack, wind owSize, state这些状态信息。
以链表形式组织多个连接,nextTcb指向下一个连接的数据结构。
TCP 分组接收函数stud_tcp_input( )首先,检查校验和;然后通过字节序转换获取相应的信息,检查序列号。
如果序列号不正确,则调用tcp_DiscardPkt;最后将报文交由输入有限状态机处理,有限状态机对报文进行处理,转换状态。
根据当前的状态并调用stud_tcp_output 函数完成tcp 建连、数据传递时返回ACK、tcp 断连等工作TCP 分组发送函数stud_tcp_output ( )判断需要发送的报文类型,根据报的类型对包中的相应字段进行设置,判断是否可以发送(发送窗口不为0)。
构造TCP 数据报文并发送。
填写TCP 报文各字段的内容和数据,转换字节序,计算校验和,然后调用发送流程的下层接口函数sendIpPkt( )发送。
stud_tcp_socket ( )函数分配相应的socketfd并且新建TCB表项,并对成员变量进行初始化stud_tcp_connect ( )函数设定目的IPv4 地址和端口,源IPv4 地址和端口;初始化TCB 结构中的相关变量;设定TCB 中的输入状态为SYN-SENT,及其它相关变量,准备发送SYN 报文;调用发送流程的下层接口函数stud_tcp_output ( )发送SYN 报文(发送类型为PACKET_TYPE_SYN);等待“三次握手”完成后返回,建立连接成功;或者出错返回。
stud_tcp_send ( )函数判断是否处于ESTABLISHED 状态;将应用层协议的数据拷贝到TCB 的输入缓冲区;调用stud_tcp_output ( )发送TCP 的数据报文(发送类型为PACKET_TYPE_DATA);同时等待ACK以实现停等式协议stud_tcp_recv ( )函数判断是否处于ESTABLISHED 状态;从TCB 的输入缓冲区读出数据;将数据交给应用层协议。
stud_tcp_close ( )函数在正常情况下(ESTABLISHED 状态),进行相应状态转换,非正常情况下(SYN-SENT 状态),直接删除TCB 结构后退出;调用发送流程下层接口函数stud_tcp_output ( )发送FIN 报文(发送类型为PACKET_TYPE_FIN);等待回应的ACK 报文,收到后成功返回,或者出错返回;删除相应的TCB表项。
实验总结通过本次实验,加深了对TCP 协议的原理和设计实现的机制的了解,对TCP协议有了更具体的认识,对概论课的学习有很大的帮助!附:上机代码(注释)#include "sysInclude.h"extern void tcp_DiscardPkt(char *pBuffer, int type);extern void tcp_sendReport(int type);extern void tcp_sendIpPkt(unsigned char *pData, UINT16 l en, unsigned int srcAddr, unsigned int dstAddr, UINT8 ttl);extern int waitIpPacket(char *pBuffer, int timeout);extern unsigned int getIpv4Address();extern unsigned int getServerIpv4Address();#define BUFFER_SIZE 1024#define TIMEOUT 5enum status{CLOSED,SYN_SENT,ESTABLISHED,FIN_WAIT_1,FIN_WAIT_2,TIME_WAIT}; //状态int gSrcPort = 2007;int gDstPort = 2006;int gSeqNum = 1;int gAckNum = 0;struct TCB {int socketfd;UINT32 srcAddr;UINT32 dstAddr;UINT16 srcPort;UINT16 dstPort;UINT32 seq;UINT32 ack;UINT16 wind owSize;UINT8 state;TCB *nextTcb;TCB() { // 用于TCP报文接收发送流程socketfd = 0;srcAddr = getIpv4Address();dstAddr = getServerIpv4Address();srcPort = gSrcPort;dstPort = gDstPort;seq = gSeqNum;ack = gAckNum;windowSize = 1;state = CLOSED;nextTcb = NULL;}TCB(int fd) { // 用于客户端socket函数的构建函数socketfd = fd;seq = gSeqNum;ack = gAckNum;windowSize = 1;state = CLOSED;nextTcb = NULL;}};UINT16 Cal cChecksum(char *pBuffer, int l en, UINT32 srcAddr, UINT32 dstAddr) {int tcp_l en = l en + 12;UINT32 checkSum = 0;if(tcp_l en & 0x1 == 1)tcp_l en += 1;char *buffer = new char[tcp_l en];memset(buffer, 0, tcp_l en);memcpy(buffer + 12, pBuffer, l en);*((UINT32 *)buffer) = htonl(srcAddr);*((UINT32 *)(buffer + 4)) = htonl(dstAddr);buffer[9] = 6; // 传输层协议号*((UINT16 *)(buffer + 10)) = htons(l en);for (int i = 0; i < tcp_l en; i += 2) {checkSum += *((UINT16 *)(buffer + i));}checkSum = (checkSum & 0xFFFF) + (checkSum >> 16);checkSum = ~checkSum;return checkSum;}TCB *tcbLinkTabl e = NULL; // TCB链表/* 通过两端的IP地址和端口号寻找TCB表项*/TCB* findTCB(UINT32 srcAddr, UINT16 srcPort, UINT32 dstAddr, UINT16 dstPort){TCB* tcb = tcbLinkTabl e;whil e(tcb != NULL){if((tcb->srcAddr == srcAddr) && (tcb->srcPort == srcPort) && (tcb->dstAddr == dstAddr) && (tcb->dstPort == dstPort))return tcb;tcb = tcb->nextTcb;}return NULL;}int stud_tcp_input(char *pBuffer, unsigned short l en, unsigned int srcAddr, unsigned int dstAddr){/* 检查校验和*/if (Cal cChecksum(pBuffer, l en, ntohl(srcAddr), ntohl(dstAddr)) != 0)return -1;UINT16 srcPort = ntohs(*(UINT16 *)pBuffer);UINT16 dstPort = ntohs(*(UINT16 *)(pBuffer + 2));UINT32 seq = ntohl(*((UINT32 *)(pBuffer + 4)));UINT32 ack = ntohl(*((UINT32 *)(pBuffer + 8)));UINT8 flags = (pBuffer[13] & 0x13);TCB *tcb = findTCB(ntohl(dstAddr), dstPort, ntohl(srcAddr), srcPort);if(tcb == NULL){return -1;}if(ack != tcb->seq + 1){tcp_DiscardPkt(pBuffer, STUD_TCP_TEST_SEQNO_ERROR);return -1;}/* 有限状态机转换*/if((tcb->state == SYN_SENT) && (flags == 0x12)){tcb->seq = ack;tcb->ack = seq + 1;stud_tcp_output(NULL, 0, PACKET_TYPE_ACK, tcb->srcPort, tcb->dstPort, tcb->srcAddr, tcb->dstAddr);tcb->state = ESTABLISHED;}else if((tcb->state == FIN_WAIT_1) && (flags == 0x10)){tcb->state = FIN_WAIT_2;}else if((tcb->state == FIN_WAIT_2) && (flags == 0x11)){tcb->ack = seq + 1;tcb->seq = ack;tcb->state = TIME_WAIT;stud_tcp_output(NULL, 0, PACKET_TYPE_ACK, tcb->srcPort, tcb->dstPort, tcb->srcAddr, tcb->dstAddr);tcb->state = CLOSED;}return 0;}void stud_tcp_output(char *pData, unsigned short l en, unsigned char flag, unsigned short srcPort, unsigned short dstPort, unsigned int srcAddr, unsigned int dstAddr){TCB *tcb = findTCB(srcAddr, srcPort, dstAddr, dstPort); // 寻找TCB项if(tcbLinkTabl e == NULL) // 用于TCP报文接收发送流程{tcb = new TCB();tcbLinkTabl e = tcb;}if(tcb == NULL || tcb->wind owSize == 0)return;/* 构造新的发送报文*/unsigned char *packet = new unsigned char[l en + 20];memset(packet, 0, l en + 20);memcpy(packet + 20, pData, l en);*(UINT16 *)(packet) = htons(tcb->srcPort);*(UINT16 *)(packet + 2) = htons(tcb->dstPort);*(UINT32 *)(packet + 4) = htonl(tcb->seq);*((UINT32 *)(packet + 8)) = htonl(tcb->ack);packet[12]=20<<2;switch(flag){case PACKET_TYPE_SYN:packet[13]=0x02;tcb->state = SYN_SENT; // 发送SYN报文,状态转移为SYN_SENTbreak;case PACKET_TYPE_ACK:packet[13]=0x10;break;case PACKET_TYPE_SYN_ACK:packet[13]=0x12;break;case PACKET_TYPE_FIN:packet[13]=0x01;break;case PACKET_TYPE_FIN_ACK:packet[13]=0x11;tcb->state = FIN_WAIT_1;break;case PACKET_TYPE_DATA:break;}*((UINT16 *)(packet+14))=htons(tcb->windowSize);*((UINT16 *)(packet+16))=Cal cChecksum((char *)packet, l en + 20, srcAddr, dstAddr);tcp_sendIpPkt(packet, l en + 20, tcb->srcAddr, tcb->dstAddr, 255);return;}int stud_tcp_socket(int domain, int type, int protocol){static int socketfd = 1;TCB *tcb = new TCB(socketfd++);tcb->nextTcb = tcbLinkTabl e;tcbLinkTabl e = tcb;return tcb->socketfd;}int stud_tcp_connect(int sockfd, struct sockaddr_in *addr, int addrl en){char buffer[BUFFER_SIZE];TCB* tcbPointer = tcbLinkTabl e;whil e((tcbPointer != NULL) && (tcbPointer->socketfd != sockfd))tcbPointer = tcbPointer->nextTcb;TCB *tcb = tcbPointer; // 找到TCB相应表项if(tcb == NULL)return -1;/* 初始化源和目的的地址及端口号*/tcb->srcAddr = getIpv4Ad dress();tcb->srcPort = gSrcPort;tcb->dstAddr = ntohl(addr->sin_addr.s_addr);tcb->dstPort = ntohs(addr->sin_port);/* 建立连接:发送SYN报文*/stud_tcp_output(NULL, 0, PACKET_TYPE_SYN, tcb->srcPort, tcb->dstPort, tcb->srcAddr, tcb->dstAddr);/* 接收SYN_ACK报文*/if(waitIpPacket(buffer, TIMEOUT) == -1 || (buffer[13] & 0x13) != 0x12)return -1;tcb->seq = ntohl(*((UINT32 *)(buffer + 8)));tcb->ack = ntohl(*((UINT32 *)(buffer + 4))) + 1;/* 发送ACK报文,建立连接完成*/stud_tcp_output(NULL, 0, PACKET_TYPE_ACK, tcb->srcPort, tcb->dstPort, tcb->srcAddr, tcb->dstAddr);tcb->state = ESTABLISHED;return 0;}int stud_tcp_send(int sockfd, const unsigned char *pData, unsigned short datal en, int flags){char buffer[BUFFER_SIZE];TCB* tcbPointer = tcbLinkTabl e;whil e((tcbPointer != NULL) && (tcbPointer->socketfd != sockfd))tcbPointer = tcbPointer->nextTcb;TCB *tcb = tcbPointer; // 找到TCB相应表项if(tcb == NULL || tcb->state != ESTABLISHED)return -1;/* 发送DATA报文*/stud_tcp_output((char *)pData, datal en, PACKET_TYPE_DATA, tcb->srcPort, tcb->dstPort, tcb->srcAddr, tcb->dstAddr);/* 等待接收ACK */if(waitIpPacket(buffer, TIMEOUT) == -1)return -1;if((buffer[13] & 0x13) != 0x10)return -1;tcb->seq = ntohl(*((UINT32 *)(buffer + 8)));tcb->ack = ntohl(*((UINT32 *)(buffer + 4))) + 1;return 0;}int stud_tcp_recv(int sockfd, unsigned char *pData, unsigned short datal en, int flags){char buffer[BUFFER_SIZE];int l en = 0;TCB* tcbPointer = tcbLinkTabl e;whil e((tcbPointer != NULL) && (tcbPointer->socketfd != sockfd))tcbPointer = tcbPointer->nextTcb;TCB *tcb = tcbPointer;if(tcb == NULL || tcb->state != ESTABLISHED)return -1;/* 等待接收数据*/if((l en = waitIpPacket(buffer, TIMEOUT)) == -1)return -1;int header_l ength = (buffer[12] >> 2) & 0x3C;memcpy(pData, buffer + header_l ength, l en - header_l ength);tcb->seq = ntohl(*((UINT32 *)(buffer + 8)));tcb->ack = ntohl(*((UINT32 *)(buffer + 4))) + (l en - header_l ength);stud_tcp_output(NULL, 0, PACKET_TYPE_ACK, tcb->srcPort, tcb->dstPort, tcb->srcAddr, tcb->dstAddr);return 0;}int stud_tcp_cl ose(int sockfd){char buffer[BUFFER_SIZE];TCB *pre = NULL;TCB *tcb = tcbLinkTabl e;whil e((tcb != NULL) && (tcb->socketfd != sockfd)){pre = tcb;tcb = tcb->nextTcb;}if(tcb == NULL)return -1;if(tcb->state != ESTABLISHED){if(pre != NULL){pre->nextTcb = tcb->nextTcb;}else{tcbLinkTabl e = tcb->nextTcb;}del ete tcb;return -1;}stud_tcp_output(NULL, 0, PACKET_TYPE_FIN_ACK, tcb->srcPort, tcb->dstPort, tcb->srcAddr, tcb->dstAddr);if(waitIpPacket(buffer, TIMEOUT) == -1)return -1;if((buffer[13] & 0x13) == 0x10){tcb->state = FIN_WAIT_2;tcb->seq = ntohl(*((UINT32 *)(buffer + 8)));tcb->ack = ntohl(*((UINT32 *)(buffer + 4))) + 1;if(waitIpPacket(buffer, TIMEOUT) == -1)return -1;if((buffer[13] & 0x13) == 0x11){tcb->state = TIME_WAIT;tcb->ack = ntohl(*((UINT32 *)(buffer + 4))) + 1;tcb->seq = ntohl(*((UINT32 *)(buffer + 8)));stud_tcp_output(NULL, 0, PACKET_TYPE_ACK, tcb->srcPort, tcb->dstPort, tcb->srcAddr, tcb->dstAddr);}else{return -1;}}else{return -1;}if(pre != NULL)pre->nextTcb = tcb->nextTcb;elsetcbLinkTabl e = tcb->nextTcb;del ete tcb;return 0;}。