TCP首部: TCP数据被封装在一个IP数据报中,如下: ? TCP首部数据格式: ?...16位源都口号:16位目的端口号用于寻找发送端和接收端的应用进程,加上IP首部的源端IP及终端IP,唯一的确认一个TCP连接。...4位首部长度:首部中32bits字的数目,TCP最多有60字节的长度,除去任选字段,正常为20字节。...16位窗口大小:TCP流量控制,字节数,起始于确认序列号指明的值,接收端期望收到的字节,最大为65535. 16位检验和:包括计算TCP首部和数据综合的二进制反码和检验和。
第17章 TCP:传输控制协议 17.3 TCP的首部 T C P数据被封装在一个I P数据报中,如图1 7 - 1所示。 ? 图1 7 - 2显示T C P首部的数据格式。...只有A C K标志(下面介绍)为 1时确认序号字段才有效。 发送A C K无需任何代价,因为 32 bit的确认序号字段和A C K标志一样,总是T C P首部的一部分。...首部长度给出首部中 32 bit字的数目。需要这个值是因为任选字段的长度是可变的。这个字段占4 bit,因此T C P最多有6 0字节的首部。然而,没有任选字段,正常的长度是 2 0字节。...检验和覆盖了整个的T C P报文段:T C P首部和T C P数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。...我们将在 1 8章中看到在一个连接建立和一个连接终止时,双方交换的报文段仅有 T C P首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。
,本文相当于该篇文章的详细版本,看完有助于更加透彻地了解本文 TCP协议是网络传输中十分重要的组件,如果用一句话来描述TCP协议:TCP是一个可靠的(reliable)、面向连接的(connection-oriented...)、基于字节流的(byte-stream)、全双工的(full-duplex)协议,而本篇文章将会带大家全面了解TCP协议中的基石——TCP首部信息 TCP协议首部字段总览 源端口与目标端口 通过使用wireShark...Flags 在往下就是TCP的标记了,在标记之前有头部长度,主要用于确定读取多少长度的头部字段,保留位可以由用户自定义字段实现特定功能,接下来我们详细介绍一下TCP的这些标记位: SYN(Synchronize...抓包后,展示的窗口大小为65536: 可选项 可选项的格式如下: 例如以最大报文数据段(MSS)为例,下面对应例子中的kind=2,length=4,value=1460: TCP常用来定义的选项有以下几个...1000,2001~5000}则表示中间1001~2000的序列号没有收到,在数据包丢失要进行重传的场景下作用显著 Window Scale:窗口缩放选项,范围为0~14 好了以上就是关于TCP首部字段的全部拆解与分析了
,不理解含义 实际传输中TCP报文段要先传送到IP层,加上IP首部后再传到数字链路层(TCP/IP位于运输层),加上数据链路层首部和尾部后才会被发送到物理链路。...太长TCP会自己进行划分,太短,TCP会存下来等到一定程度后再发送。 TCP连接 TCP连接的端点叫做socket、套接字或插口。每个TCP连接有两个端点,具体定义如下: P.S....报文段中有一部分是长度不确定的选项字段,所以需要数据偏移来指出TCP报文段首部的长度,不然没办法知道数据段从哪里开始(这也是为什么这一段叫做“数据偏移”,虽然其实他就是记录报文段首部的长度) 保留:6位...例如Control + C的中断指令,如果已经缓存了一堆要发送的数据,突然用户反悔了(相信我,用户就是渣男/女,天天反悔,嗯),不想传了,就会按下中断指令Control + C。...计算式要在报文段前加上12字节的伪首部,格式与UDP的伪首部一样,除了第四个字段中的17要改为6(TCP协议号为6),第5字段中UDP长度改为TCP长度。接收方接收到报文要检验的时候也要加上伪首部。
目录 TCP/IP协议介绍 TCP/IP协议与WinSock网络编程接口的关系 WinSock编程简单流程 VC中socket编程...、软件需求的定义。...TCP/IP协议确切的说法应该是TCP/UDP/IP协议。UDP协议(User Datagram Protocol 用户数据报协议),是一种保护消息边界的,不保障可靠数据的传输。...所以有很多人在使用TCP协议通讯的时候,并不清楚TCP是基于流的传输,当连续发送数据的时候,他们时常会认为TCP会丢包。...实际上,WinSock就是TCP/IP协议的一种封装,你可以通过调用WinSock的接口函数来调用TCP/IP的各种功能.例如我想用TCP/IP 协议发送数据,你就可以使用WinSock的接口函数Send
年获评百大博主、华为云享专家、阿里云专家博主、掘金优秀创作者、全网粉丝量6w+、全网访问量100w+ 本文章内容由 謓泽 原创 如需相关转载请提前告知博主 ⚠ 个人主页:謓泽的博客 专栏系列:【C】...不带参数的宏的定义方式如下(这也是我们经常用到的宏定义) #define 宏名 字符串 //没有分号,说没有分号倒不如说最好不要加分号 这里说下原因吧:因为宏定义它并不是C语言的语句,所以不用加分号...宏名实际上就是一个标识符,必须要符合C语言当中标识符的语法规定的。 标识符的规则:字母、数字、下划线,不以数字开头,注意:关键字不能作为标识符!...所以语言本身就会没办法帮我们区分二者的一些使用。那么我们平时写宏或者函数的时候的习惯是↓ 宏明全部大写形式。 函数明不要全部大写,建议第一个字母大写。...正确写法是要在宏字符串带上双引号✔ #define Name "chenze" 小知识点⇢宏是可以用来充当注释的效果的这个我在接触宏的时候我都没有想到这个问题,那么现在我们用BSC充当C+
拓展: 数组指针定义(以整型数组为例): int a[3]; // 整型数组 int (*p)[3]; // 整型数组指针 指针数组定义(以整型指针为例): int *p; // 整型指针 int *a...[3]; // 整型指针数组 函数指针定义(以函数void f(int)为例): void f(int); // 普通函数 void (*p)(int); // 函数指针 指针函数定义(以返回整型指针为例
C语言宏定义详解 在C语言中,宏定义是一种强大的预处理器功能,用于在编译之前对代码进行替换和条件编译。宏定义通过预处理器指令进行定义和使用,能够使代码更加灵活和可维护。...本文将对C语言中的宏定义进行全面的讲解,包括各种相关的预处理器指令及其用法。 1. 宏定义关键词总览 关键词 用途 #define 定义宏(常量宏或函数宏)。...("Current line: %d\n", __LINE__); return 0; } 在这个示例中,#line 100 "newfile.c" 将当前行号设置为100,并将文件名设置为 newfile.c...总结 C语言中的宏定义是一种强大的预处理器功能,用于在编译之前对代码进行替换和条件编译。...理解这些宏定义的用法可以帮助开发人员编写更加高效和可维护的代码。 16. 结束语 本节内容已经全部介绍完毕,希望通过这篇文章,大家对C语言宏定义有了更深入的理解和认识。
“要成为绝世高手,并非一朝一夕,除非是天生武学奇才,但是这种人…万中无一” ——包租婆 这道理放在C语言学习上也一并受用。...在编程方面有着天赋异禀的人毕竟是少数,我们大多数人想要从C语言小白进阶到高手,需要经历的是日积月累的学习。 那么如何学习呢?当然是每天都练习一道C语言题目!! ? 作者 闫小林 白天搬砖,晚上做梦。...例89:学习C语言register定义变量的用法。 解题思路:register这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。...因为,如果定义了很多register变量,可能会超过CPU的寄存器个数,超过容量。...C语言源代码演示: #include//头文件 int main()//主函数 { register int i;//定义寄存器变量 int temp=0;//定义整型变量
错误显示在h文件504行处有先前定义的位置,这是因为库文件里已经存在这个变量了,再于头文件定义该变量就会报错,解决方法就是注释掉头文件对该变量的定义。
第一种 //使用typedef将 struct poly_node定义一个别名 poly_node typedef struct poly_node{ int coef; int exp...struct poly_node * next; }poly_node; poly_node node1; 第二种 //定义结构体类型poly_node的同时定义结构体变量node1...poly_node{ int coef; int exp struct poly_node * next; }node1; struct poly_node node2; //之后再这样定义...第三种 //直接定义结构体变量node1 struct { int coef; int exp struct poly_node * next; }node1;
“要成为绝世高手,并非一朝一夕,除非是天生武学奇才,但是这种人…万中无一” ——包租婆 这道理放在C语言学习上也一并受用。...在编程方面有着天赋异禀的人毕竟是少数,我们大多数人想要从C语言小白进阶到高手,需要经历的是日积月累的学习。 那么如何学习呢?当然是每天都练习一道C语言题目!! ? 作者 闫小林 白天搬砖,晚上做梦。...例88:学习使用C语言auto定义变量的用法。 解题思路:auto自动存储类型,一般我们很少在程序中显示申明变量为auto类型。...C语言源代码演示: #include//头文件 int main()//主函数 { int i,num;//定义整型变量 num=2;//赋初值 for (i=0;
例89:学习C语言register定义变量的用法。 解题思路:register这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。...因为,如果定义了很多register变量,可能会超过CPU的寄存器个数,超过容量。...C语言源代码演示: #include//头文件 int main()//主函数 { register int i;//定义寄存器变量 int temp=0;//定义整型变量...以上,如果你看了觉得对你有所帮助,就给小林点个赞,分享给身边的人叭,这样小林也有更新下去的动力,跪谢各位父老乡亲啦~ C语言学习路线 C语言开发工具 更多案例可以go公众号:C语言入门到静通
C语言宏定义技巧(常用宏定义) 写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性等等。下面列举一些成熟软件中常用得宏定义。...) ( ((c) >= 'a' && (c) c) - 0x20) : (c) ) 13、判断字符是不是10进值的数字 #define DECCHK( c ) ((c) >= '0' && (c) <= '9') 14、判断字符是不是16...进值的数字 #define HEXCHK( c ) ( ((c) >= '0' && (c) <= '9') ||\ ((c) >= 'A' && (c...可以定义宏,例如: 当定义了_DEBUG,输出数据信息和所在文件所在行 #ifdef _DEBUG #define DEBUGMSG(msg,date) printf(msg);printf(“%d
上篇文章中做了UDP打洞,这篇当然就会是TCP打洞了,两个处于不同内网的两台机器如何通过TCP/IP协议进行链接通讯呢?这其实跟UDP打洞差不多,基本步骤是这个样子的。...与端口连接A 这样A与B就成功连接了,这里需要注意的一点就是两个socket在同一个端口绑定的问题,socket提供了setsockopt函数,其中参数SO_REUSEADDR可以解决这个问题 下面是c语言代码示例
rlt = 1; return rlt; } m_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP...### #makefile ######################################## BINARY= libmytcp CC= gcc LD= ld CFLAGS= -std=c99...LDSCRIPT= -lws2_32 LDFLAGS= -Llib OBJS= NC_ComLib.o #CFLAGS=-std=c99 .PHONY: clean all:images images...: (BINARY).a(OBJS):%.o:%.c(CC) -c (CFLAGS) < -o (OBJS)ar crv (*).a
文章目录 一、TCP 协议 特点 二、TCP 报文段首部格式 三、TCP 报文段首部 6 控制位 一、TCP 协议 特点 ---- TCP 协议 特点 : ① 面向连接 : TCP 协议的连接是 “...数据 看做 无结构的字节流 ; 二、TCP 报文段首部格式 ---- TCP 报文段首部格式 : ① TCP 报文段组成 : 由 TCP 首部 和 TCP 数据部分 组成 ; ② TCP 首部格式...: 由 20 字节固定首部 + 可变的选项 + 填充部分 组成 ; 其中 可变选项 + 填充部分 是 4 字节整数倍 , 填充部分的意义就是为了让整个 TCP 首部大小是 4 字节整数倍 ;...; ⑥ 数据偏移 : TCP 报文段 数据部分起始位置 , 距离 TCP 报文段的起始位置 , 有多远 , 单位 4 字节 ; 即 整个 TCP 报文段 中 TCP 首部的长度 ; ⑦ 窗口 :...首部是 4 字节整数倍 ; 三、TCP 报文段首部 6 控制位 ---- TCP 报文段首部 6 控制位 : ① URG ( 紧急位 ) : URG = 1 时 , 表明 该报文段中有紧急数据
定义及功能: #include #define offsetof(type, member) (size_t)&(((type*)0)->member) 获取类型type...offsetof_test.c -o offsetof_test.o gcc -o main offsetof_test.o ..../main 运行结果: 函数print_offsetof实现中,主要使用了 offsetof宏定义来获取一个结构体中的各个成员相对于结构体首地址的偏移量 根据结构体定义,不难理解上述输出的结果。...其中age是结构体定义中的第一项,它相对于结构体首地址的偏移地址为0 fullname是结构体的第二项,它相对于结构体首地址的偏移量为 age类型占用的字节数,为4 以后一次类推。...如果将fullname_ptr转换为(int *)类型,这样再减4的时候,会在0x8fde00c的基础上,减掉16个字节。
简单宏定义 简单的宏定义有如下格式: [#define指令(简单的宏)] #define 标识符替换列表 替换列表是一系列的C语言记号,包括标识符、关键字、数、字符常量、字符串字面量、运算符和标点符号...虽然简单的宏常用于定义常量名,但是它们还有其他应用。 4) 、可以对C语法做小的修改。实际上,我们可以通过定义宏的方式给C语言符号添加别名,从而改变C语言的语法。...例如,对于习惯使用Pascal的begin和end(而不是C语言的{和})的程序员,可以定义下面的宏: #define BEGIN { #define END } 我们甚至可以发明自己的语言。...##运算符 在C语言的宏中,"##"被称为 连接符(concatenator),它是一种预处理运算符, 用来把两个语言符号(Token)组合成单个语言符号。...上面提到了两种将宏定义为空的定义方式,看上去一样,实际上只要明白了宏都只是简单的代码替换就知道该如何选择了。 8. 预定义宏 在C语言中预定义了一些有用的宏, 见表预定义宏。
领取专属 10元无门槛券
手把手带您无忧上云