【计算机网络】——TCP协议简介以及TCP编程

1、TCP概述

1.1TCP含义

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

【特点】

  1. 面向连接型的传输协议:每一次完整的数据传输都要经过建立连接、使用连接、终止连接的过程;
  2. 仅支持单播传输,支持全双工传输
  3. TCP连接是基于字节流的,而非报文;传输单位为数据段,每次发送的TCP数据段大小和数据段数都是可变的;

【优点】可靠、稳定

  • TCP在数据传递之前,会有三次握手来建立连接连接
  • 在数据传递时,采用校验和,序列号,确认应答,超时重传,流量控制,滑动窗口等机制保证了可靠,提高了性能。
  • 在数据传送完后,会断开连接以节约资源。

【缺点】速度慢、效率低、易被攻击

  • 因为在TCP传送数据前,要建立连接,耗费时间,数据传递中又适用了很多机制来保证其可靠,也会消耗大量的时间。
  • 它要维护所有传输连接,每个连接都会占用系统的CPU,内存等资源
  • 在三次握手确认连接时,容易受到DOS、STN洪泛攻击等。

由此,也可以总结出,TCP适用于对可靠性、数据的传输质量要求高,但对实时性要求不高的场景。

1.2TCP首部报文格式

TCP虽然是面向字节流的,但TCP传送的数据单元却是报文段。一个TCP报文段分为了首部和数据部分,而TCP的全部功能都体现在它首部中的各字段的作用。下图则表示的TCP的首部,TCP首部的前20个字节是固定的,后面40个字节段是根据需要而增加的选项,因此TCP的最小长度是20字节。
在这里插入图片描述
下面,我们就来说明一下各字段的意义
1、源端口和目的端口
因为我们知道两台主机之间的通信实际上就是主机上两个进程的通信,端口号就是用来标识进程的

2、32位序号(seq)
因为其占4个字节,序号范围是[0,232-1],共232个序号。在一个TCP连接中传送的字节流中的每一个字节都是按照顺序编号,初始值是系统内核随机产生的值加上报文段的第一个数据在整个字节流中的偏移量,也就是说越往后的数据,32位序号值就越大。
【举个栗子】
一报文段的序号字段值是301,而携带的数据共有100字节。这就表明:本报文段的数据的第一个字节的序号是301,最后一个字节的序号是400.显然,下一个报文段的数据序号应当从401开始,即下一个报文段的序号字段的值应为401,这个字段的名称也叫做“报文段序号”

3、32位确认号(seq)
占4个字节,是期望收到对方下一个报文段的第一个数据字节的序号
【举个栗子】
B正确收到了A发送过来的一个报文段,其序号段值是501,数据长度是200字节(序号501-700),这就表明B正确收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701.因为接收到的报文段的序号值+报文段长度+1,所以若确认号=N。则表明:到序号N-1为止的所有数据都已正确收到

有了序号和确认号,我们就来再次解释一下三次握手过程各字段的含义。从下图中可以看到
在这里插入图片描述
首先客户端在发送请求连接的时候序号值为i,服务器对其发送一个确认信息,因为没有携带数据,所以ack=i+1,这是服务器发送的请求确认所以序号值为j,最后客户端的确认ack=j+1.

4、数据偏移
就是指出TCP报文段的首部长度。我们都知道TCP首部固定长度是20字节,但是还有选项部分。
【注意】
数据偏移的单位是32位字(也就是4字节),由于4位二进制能够表示的最大十进制数字是15,所以数据偏移的最大值是60字节,这就是TCP首部的最大长度(即选项长度不能超过40字节)

5、保留
占6位,保留为今后使用,目前置为0

6、选项
URG置为1时:表示紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送而不是按原来的排队顺序来传送

ACK置为1时:TCP规定,在连接建立后所有传送的报文段都必须把ACK置为1

PSH置为1时:接收方收到PSH=1的报文段,就尽快地交付给接收应用进程,而不是等到整个缓存都填满了后再向上交付

RST置为1时:表示TCP连接出现了严重差错,必须释放连接,然后再重新建立运输连接。还可以用来拒绝一个非法的报文段或拒绝打开一个连接

SYN置为1时:用来同步序号。表示这是一个连接请求或接受接受报文

FIN置为1时:用来释放一个连接。表明此报文段的发送方的数据已发送完毕。

7、窗口
该窗口占两个字节,窗口值是[0,216-1]之间的整数。该窗口值作为接收方让发送方设置发送窗口的依据。
【举个栗子】
设确认号是701,窗口字段是1000,这就表明,从701号算起,发送此报文段的一方还要接收1000个字节数据(字节序号是701-1700)的接收缓存空间

8、校验和
使用CRC冗余校验来检验TCP的头部和数据部分。

9、紧急指针
占2字节,该字段只有在URG=1的时候才有意义,它指出了本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。

10、选项
长度可变,最长可达40字节。当没有使用选项时,TCP的首部长度是20字节

1.3理解源IP地址和目的IP地址

一般的,在IP数据报的头部,有两个IP地址,一个是源IP地址,一个是目的IP地址,他代表着这个数据包从哪里来准备往哪里去。

【例子】

  • 西游记大家不陌生吧,唐僧西天取经,每到一个地方有人问唐僧你从哪里来准备去哪,唐僧回答的都是
    “贫僧从东土大唐而来,去往西天取经”,那我们就知道了,唐僧的源地址是东土大唐,目的地址是西天,这是一直都不会变的,我们说的源IP地址和目的IP地址也是一样的道理
  • 但是我们想想我们是不是有一个IP地址之后就能够完成通信了呢,就像唐僧到西天是不是就可以取经了呢,答案很明显是不是,那唐僧到了西天,应该具体到西天的哪才能取到真经,就像我们应该将信息发到目的IP地址处的哪台主机上的哪个进程才能被接收呢?

1.4认识端口号

我们都知道,实现两个主机的通信实际上是实现两个主机上的两个进程之间的通信。其实端口号就是用来标识一个进程的,告诉操作系统,当前的这个数据要交给哪一个进程来处理。
1、特点

  1. 端口号是一个2字节16位的整数
  2. IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;
  3. PID和端口号都是标识一个唯一进程的。但是他们的区别是进程PID是只要有一个进程都有进程PID。而端口号主要表示需要使用网络的进程才会有端口号

2、常见的端口号
端口号的范围是从1-65535。对其进行了如下的分类:

范围 含义
0~1023 被公认的服务占用了,用户不能使用,如Web服务占用80端口
1024~49151 用户自己使用的端口号,即自己定义TCP编程sockaddr_in结构体的成员port端口号
49152~65535 用于自动分配,如我们电脑安装的客户端程序

【一些常见的端口号及其用途如下】
TCP 21端口:FTP 文件传输服务
TCP 23端口:TELNET 终端仿真服务
TCP 25端口:SMTP 简单邮件传输服务
UDP 53端口:DNS 域名解析服务
TCP 80端口:HTTP 超文本传输服务
TCP 110端口:POP3 “邮局协议版本3”使用的端口
TCP 443端口:HTTPS 加密的超文本传输服务
TCP 1521端口:Oracle数据库服务
TCP 1863端口:MSN Messenger的文件传输功能所使用的端口
TCP 3389端口:Microsoft RDP 微软远程桌面使用的端口
TCP 5631端口:Symantec pcAnywhere 远程控制数据传输时使用的端口
UDP 5632端口:Symantec pcAnywhere 主控端扫描被控端时使用的端口
TCP 5000端口:MS SQL Server使用的端口
UDP 8000端口:腾讯QQ

注:在Linux下使用cat /etc/serveices可查看知名的端口号

3、端口号补充
3.1同一个端口可以被TCP,UDP应用程序同时使用
首先端口可以形象地比喻成操作系统上的编号唯一的文件,端口的唯一性的标识不是端口号,而是端口号和协议名称的组合,应用程序和协议寻址时就是靠的这个组合。我们可以使用netstat -an查看详细的网络状况,可以看到UDP和TCP的协议号不同。

3.2同一个应用程序可以创建多个套接字
一个网络应用程序只能绑定一个端口( 一个套接字只能绑定一个端口 )。TCP/IP中识别一个进行通信的应用需要5大要素,它们分别为:源IP地址,目标IP地址,源端口,目标端口,协议号,只要端口不同,就可以建立多个socket

2、网络编程基础API

2.1创建socket

#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain, int type, int protocol);

【功能】
socket就是一个可读、可写、可控制、可关闭的文件描述符,socket系统调用可创建一个soket.
【参数】

  1. domain:主要是告诉系统使用哪个底层协议簇。
    1.1常用的TCP有两种,IPV4的是PF_INET,IPV6的是PF_INET6;
    1.2对于UNIX本地域协议族该参数应该设置为PF_UNIX

  2. type:表示可以接受参数一的服务类型与下面两种重要的标志相与的值。
    2.1TCP/IP协议,其取值SOCK_STREAM
    2.2UDP协议是SOCK_DGRAM

  3. protocol:在前面两个参数构成的协议集合下,再选择一个具体的协议。不过这个值通常都是唯一的,所以一般情况下都应该把它设置成0表示使用默认协议

  4. 返回值:成功返回socket文件描述符,失败返回-1并设置errno.

代码实现:

	int listenfd = socket(AF_INET, SOCK_STREAM, 0);
	assert(listenfd != -1);

2.2命名socket——bind

上述的创建socket相当于我们给它指定了地址簇,但是并没有指定使用该地址簇中的哪个具体socket地址
就相当于我们买了一个手机但是并没有安装电话卡。将一个socket与socket地址绑定称为给socket命名。其定义如下:

int bind(int socket, const struct sockaddr *address,socklen_t address_len);

【功能】

  1. 只有命名后客户端才能知该如何连接它就相当于一个手机有了电话卡,
  • 0
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值