【TCP/IP网络编程】:05TCP原理 --简单描述

本篇文章主要对TCP原理进行简单的分析和讨论。

TCP套接字中的I/O缓冲

前文有介绍过TCP通信数据无边界的特性,即本端一次发送的数据对端并不一定一次性接收,那剩余的数据在哪里呢?

实际上,write函数调用后并非立即传输数据,read函数调用后也并非马上接收数据。如下图所示,write函数调用瞬间,数据将移至输出缓冲区(适当的时侯传向对方的输入缓冲);read函数调用瞬间,从输入缓冲区读取数据。

TCP套接字的I/O缓冲

TCP的I/O缓冲有如下特点:

  • I/O缓冲在每个TCP套接字中单独存在
  • I/O缓冲在创建TCP套接字时自动生成
  • 即使关闭套接字也会继续传输发送缓冲区中遗留的数据
  • 关闭套接字将丢弃输入缓冲区中的数据

考虑这样一种情况,接收端输入缓冲区大小为50字节,而发送端输出缓冲大小为100字节,当发送端向接收端传输100字节的数据时会发生什么呢?接收端缓冲区溢出?其实,接收端可以正常处理这种情况,因为TCP会控制数据流(Flow Control),这是由TCP协议的滑动窗口(Sliding Window)机制来保证的。

关于数据交换时调用的函数write和read(阻塞模式下),write函数调用的返回时机是发送端将数据传输至输出缓冲区;read函数的返回时机是接收缓冲区有数据待读取时。

 TCP内部工作原理1:与对方套接字的连接

整体来看,TCP套接字从创建到消失所经历的过程如下:

  • 与对方套接字建立连接
  • 与对方套接字进行数据交换
  • 断开与对方套接字的连接

关于TCP套接字建立连接的过程如下图所示,该过程就是所谓的三次握手(Three-way handshaking)机制。

TCP套接字连接过程

[SYN] SEQ:1000,ACK:-

首次建立连接请求时使用的消息字段为SYN(Synchronization),即收发数据前传输的同步消息。SEQ值1000表示该数据包的编号,ACK字段为空。

[SYN+ACK] SEQ:2000,ACK:1001

ACK是向对端的反馈字段,值1001表示已收到对端编号为1000的消息。

通过数据包编号并确认的方式,可以在数据丢失时马上查看并重传丢失的数据包,这也是TCP消息可靠的原因。

关于三次握手中主机A最后一次ACK消息的讨论,若该数据包丢失会发生什么?

若最后的ACK消息丢失,服务器端(主机B)并不会重传SYN+ACK消息,而是直接发送RST报文进入closed状态,目的是为了防止SYN泛洪攻击;另一个考虑,若最初客户端主机A的SYN消息受网络阻塞很久才到达服务器端,而客户端由于长久未与服务端建立连接而关闭了套接字,则此时服务器端也不能收到ACK消息的回应,因此也就没必要重发SYN+ACK消息。

TCP内部工作原理2:与对方主机的数据交换

三次握手后双方便建立了有效的连接,接下来是数据交换的过程,如下图所示。

TCP套接字数据交换过程

以上通信过程的消息字段和三次握手过程一样,需要注意的是ACK消息字段的值是这样计算的:SEQ值 + 传递的字节数 + 1。加1是为了告知对方之前发送的消息已全部接收,下次可发送其余数据。如果数据包发生丢失又会怎样?

TCP套接字数据传输错误处理

如上图示过程,为了完成数据包重传,TCP套接字启动计时器以等待ACK应答。若相应计时器发生超时(Time-out)则重传。

TCP内部工作原理3:断开与套接字的连接

TCP套接字的结束过程也非常优雅。如果对方还有数据需要传输时直接断连会出问题,所以断连时需要双方协商。该过程如下图所示,也即四次挥手(Four-way handshaking)的过程。

TCP套接字断开连接过程

携带有FIN字段的数据包表示断开连接,也就是说,双方各发送一次FIN消息后断开连接。

原文地址:https://www.cnblogs.com/Glory-D/p/12075652.html

时间: 2024-08-03 23:17:39

【TCP/IP网络编程】:05TCP原理 --简单描述的相关文章

TCP/IP网络编程读书笔记-简单的套接字编程(1)

在linux和windows下都是通过套接字编程进行网络编程.不同的系统上通信有部分差别,现在刚开始学习,给自己学习的时候一个总结. 一,socket函数的套接字步骤 第一,linux网络编程中接受连接请求(服务器端)套接字的四个步骤: 1)调用socket函数创建套接字 2)调用bind函数分配IP地址和端口号 3)调用listen函数转为可接收请求状态 4)调用accept函数受理连接请求 第二,linux网络编程中请求连接(客户端)套接字的两个步骤: 1)调用socket函数创建套接字 2

《TCP/IP网络编程》

<TCP/IP网络编程> 基本信息 作者: (韩)尹圣雨 译者: 金国哲 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787115358851 上架时间:2014-6-19 出版日期:2014 年6月 开本:16开 页码:1 版次:1-1 所属分类:计算机 > 计算机网络 > 网络协议 > TCP/IP 更多关于>>><TCP/IP网络编程> 编辑推荐 为初学者准备的网络编程 本书涵盖操作系统.系统编程.TCP/IP协议等多种

TCP/IP网络编程系列之一

概述 网络编程实际上就是编写程序使两台联网的计算机相互的交换数据.操作系统会提供名为“ 套接字 ”的部件.套接字是网络数据传输的软件设备,即使对网络数据传输原理不太熟悉也无关紧要.我们也能通过套接字完成数据传输,因此网络编程又叫套接字编程. 过程  我们可以把套接字理解为我们平时的电话机,我们先看一下套接字的创建过程: 首先你如果要和别人沟通肯定要安装好电话机才可以,所以对应套接字的是调用socket函数时进行对话. #include<sys/socket.h> int socket(int

TCP/IP网络编程系列之四(初级)

TCP/IP网络编程系列之四-基于TCP的服务端/客户端 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流的套接字.在了解TCP之前,先了解一下TCP所属的TCP/IP协议栈. 如图所示,TCP/IP协议栈共分为4层,可以理解成数据收发分成了4个层次化过程. 链路层 它是物理链接领域标准化结果,也是最基本的领域,专门定义LAN.WAN.MAN等网络标准.若两台计算机通过网络进行数据交换,链路层就负责整个物

【TCP/IP网络编程】:06基于UDP的服务器端/客户端

本篇文章简单描述了UDP传输协议的工作原理及特点. 理解UDP UDP和TCP一样同属于TCP/IP协议栈的第二层,即传输层. UDP套接字的特点 UDP的工作方式类似于传统的信件邮寄过程.寄信前应先在信封上填好寄信人和收信人的地址,之后贴上邮票放进邮筒即可.当然信件邮寄过程可能会发生丢失,我们也无法随时知晓对方是否已收到信件.也就是说信件是一种不可靠的传输方式,同样的,UDP所提供的也是一种不可靠的数据传输方式(以信件类比UDP只是通信形式上一致性,之前也以电话通信的方式类比了TCP的通信方式

TCP/IP网络编程系列之二

套接字类型与协议设置 我们先了解一下创建套接字的那个函数 int socket(int domain,int type,int protocol);成功时返回文件描述符,失败时返回-1.其中,domain是套接字使用中的协议族(Protocol Family)信息.type套接字类型里面的数据传输类型信息.protocol计算机通信中使用的协议信息. 协议族(Protocol Family) 协议族类型有: PE_INET IPV4 PE_INET6 IPV6 PF_LOCAL 本地通信的UNI

浅谈TCP/IP网络编程中socket的行为

我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: . TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) . Socket I/O系统调用(重点如read/write),这是TCP/IP协议在应用层表现出来的行为. . 编写Performant, Scalable的服务器程序.包括多线程.IO Multiplexing.非阻塞.异步等各种技术. 关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illust

TCP/IP网络编程系列之二(初级)

套接字类型与协议设置 我们先了解一下创建套接字的那个函数 int socket(int domain,int type,int protocol);成功时返回文件描述符,失败时返回-1.其中,domain是套接字使用中的协议族(Protocol Family)信息.type套接字类型里面的数据传输类型信息.protocol计算机通信中使用的协议信息. 协议族(Protocol Family) 协议族类型有: PE_INET IPV4 PE_INET6 IPV6 PF_LOCAL 本地通信的UNI

TCP/IP 网络编程 (抄书笔记 3) -- 僵尸进程和多任务并发服务器

TCP/IP 网络编程 (抄书笔记 3) – 僵尸进程和多任务并发服务器 TCP/IP 网络编程 (抄书笔记 3) – 僵尸进程和多任务并发服务器 Table of Contents 僵尸进程的产生 避免僵尸进程 信号 多任务的并发服务器 僵尸进程的产生 子进程先退出, 父进程没有退出 ==> 僵尸进程 父进程先退出, 子进程没有退出 ==> 子进程被 0 号进程回收, 不会产生僵尸进程 pid_t pid = fork(); if (pid == 0) { // child printf(&

TCP/IP网络编程系列之三

TCP/IP网络编程系列之三-地址族与数据序列 分配给套接字的IP地址和端口 IP是Internet Protocol (网络协议)的简写,是为首发网络数据而分配给计算机的值.端口号并非赋予计算机值,而是为了区分程序中创建的套接字而分配给套接字的序号. 网络地址 网络地址分为IPV4和IPV6,分别你别为4个字节地址簇和6个字节地址簇.IPV4标准的4个字节的地址分为网络地址和主机地址,且分为A.B.C.D.E 等类型.一般很少用到E类型.如下图所示:net-id指网络ID,host-id指主机