网络编程之TCP三次握手与四次挥手、基于TCP协议的套接字编程
TCP三次握手和四次挥手
背景描述
通过OSI七层网络模型中IP层的介绍,我们知道网络层,可以实现两个主机之间的通信。其实并不然,因为真正的实体是在主机的进程,是一个主机中的一个进程与另一个主机的进程在交换数据。
IP协议只是把数据发送到目的主机,但是并没有交给主机的具体应用程序。而端到端的通信才是应用程序之间的通信。
UDP:在传送数据时不需要进行连接,远地的主机在收到UDP报文后也不需要进行确认,虽然UDP不提供数据的可靠交付,但是这样会节省好多资源,开销,使得它的速度比较快,比如一些实时性要求较高的服务,经常使用UDP。对应的应用层的协议主要有DNS,TFTP,DHCP,SNMP,NFS等。
TCP: 提供面向连接的服务,在传输数据之前,必须先建立连接,传输结束后释放连接。因此TCP是一种可靠的数据运输服务,但是这样就会增加不可避免的花销。对应的应用层的协议有,SMTP,TELNET,HTTP,FTP等。
常用的熟知端口号
应用程序 | 熟知端口 | 传输层协议 |
---|---|---|
FTP | 21,20 | TCP |
TFTP | 69 | UDP |
TELNET | 23 | TCP |
SMTP | 25 | TCP |
DNS | 53 | UDP |
HTTP | 80 | TCP |
SSH | 22 | TCP |
TCP概述
TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种端点我们叫做套接字(socket),它的定义为端口号拼接到IP地址即构成套接字,例如,若IP为192.3.4.26,而端口号为80,
那么得到的套接字为192.3.4.26:80
TCP连接的建立(三次握手)
- 最开始的时候,客户端和服务端都是处于CLOSED关闭状态。主动打开连接的为客户端,被动打开的连接是服务器。如果要进入来连接,会经过如下步骤:
- TCP服务器进程先创建传输控制块TCP,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
- 客户端先创建传输控制块TCP,然后向服务器发连接请求报文,报文里包括SYN报头;
- 服务端接收到客户端传入的报文,如果同意连接,就会发出确认报文,此时报文中包括SYN和ACK报头;
- 客户端接收到服务端传来的报文,如果确认连接,就会返回给ACK报头的报文给服务端,此时客户端进入连接状态;
- 服务端接收到客户端传入的确认连接报文后,也进去连接状态,这样双发就建立了连接,可以进行通信了。
TCP四次挥手
- 数据传输完毕后,双方就可以释放连接。最开始的时候,客户端和服务端都处于ESTABLISHED(连接)状态,然后客户端主动关闭,服务端被动关闭。
- 客户端进程发出连接释放报文,并且停止发送数据。报文包括FIN报头;
- 服务端接收到包括FIN报头的释放报文,发出确认报文,ACK报头,但是此时服务端可能还会传输数据给客户端;
- 客户端接受到服务器返回的包含ACK报头的报文后,等待把最后的数据传输完毕;
- 数据传输完毕后,服务端就会像客户端发送报文,包含FIN,ACK报头,等待客户端确认;
- 客户端接收到服务端发送的释放连接报文请求后,如果要释放连接,就会返回给服务端一个ACK报头的报文,客户端进入等待状态。此时客户端的连接还没有释放,必须经过2MSL的时间后,才会释放连接;
- 服务端接收到客户端发送的包含ACK报头的报文,直接释放连接,进入CLOSDED(关闭)状态。
如果已建立连接,客户端突然断开,会怎么办呢?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
基于TCP协议的套接字编程
什么是Socket
socket是应用层与TCP/IP协议通信的中间软件抽象层,他是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议隐藏在Socket接口后面。
套接字发展史及分类
套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。
套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。
基于文件类型的套接字家族
套接字家族名字:AF_UNIX
unix一切皆文件,基于文件的套接字调用就是底层的文件系统来取数据,两个套接字进程运行在同一个机器上,可以通过访问一个文件系统间接完成通信
基于网络类型的套接字家族
套接字家族名字:AF_INET
套接字工作流程
服务端:初始化Socket---->然后端口绑定(bind)---->对端口进行监听(listen)---->调用accept接受
客户端:初始化Socket---->连接服务器(connect)
如果客户端和服务端连接成功,则可以进行连接。客户端发送信息,服务端处理请求,然后再把数据传给客户端。
import socket
# socket_family:可以为AF_UNIX或AF_INET
# socket_type:可以是SOCK_STREAM或SOCK_DGRAM
# protocol:一般不填,默认为0
socket.socket(socket_family, socket_type, protocal=0)
# 获取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
服务端套接字函数
方法 | 用途 |
---|---|
bind() | 绑定(主机,端口号)到套接字 |
listen() | 开始TCP监听 |
accept() | 被动接受TCP客户的连接,(阻塞式)等待连接的到来 |
客户端套接字函数
方法 | 用途 |
---|---|
connect() | 主动初始化TCP服务器连接 |
connect_ex() | connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 |
公共用途的套接字函数
方法 | 用途 |
---|---|
recv() | 接收TCP数据 |
send() | 发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完) |
sendall() | 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完) |
recvfrom() | 接收UDP数据 |
sendto() | 发送UDP数据 |
getpeername() | 连接到当前套接字的远端的地址 |
getsockname() | 当前套接字的地址 |
getsockopt() | 返回指定套接字的参数 |
setsockopt() | 设置指定套接字的参数 |
close() | 关闭套接字 |
面向锁的套接字函数
方法 | 用途 |
---|---|
setblocking() | 设置套接字的阻塞与非阻塞模式 |
settimeout() | 设置阻塞套接字操作的超时时间 |
gettimeout() | 得到阻塞套接字操作的超时时间 |
面向文件的套接字函数
方法 | 用途 |
---|---|
fileno() | 套接字的文件描述符 |
makefile() | 创建一个与该套接字相关的文件 |
基于TCP协议的套接字编程
服务端
# 服务端.py
import socket
# 1、初始化服务端
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 2、绑定端口
server.bind(('127.0.0.1', 8000))
# 3、建立监听
server.listen(5)
# 4、等待客户端连接
print('start...')
conn, client_addr = server.accept()
# 5、通信
data = conn.recv(1024) # 接受信息的最大字节数,默认为1024个字节
print(data.decode('utf-8')) # 数据传输的是二进制
conn.send(data.upper())
# 6、断开连接
conn.close()
# 7、关闭服务器
server.close()
客户端
# 客户端.py
from socket import *
# 1、初始化客户端
client = socket(AF_INET, SOCK_STREAM)
# 2、连接服务器
client.connect(('127.0.0.1', 8000))
# 3、通信
msg = input('请输入你想传输的信息>>>')
client.send(msg.encode('utf-8')) # 以二进制形式发送数据
data = client.recv(1024)
print(data)
# 4、关闭连接
client.close()
网络编程之TCP三次握手与四次挥手、基于TCP协议的套接字编程的更多相关文章
- TCP三次握手和四次挥手、HTTP协议
TCP三次握手和四次挥手 首先我们知道HTTP协议通常承载于TCP协议之上,HTTPS承载于TLS或SSL协议层之上 通过上面这张图我们能够知道. 在Http工作之前,Web浏览器通过网络和W ...
- 使用 tcpdump 抓包分析 TCP 三次握手、四次挥手与 TCP 状态转移
目录 文章目录 目录 前文列表 TCP 协议 图示三次握手与四次挥手 抓包结果 抓包分析 TCP 三次握手 数据传输 四次挥手 TCP 端口状态转移 状态转移 前文列表 <常用 tcpdump ...
- 用wireshark抓包分析TCP三次握手、四次挥手以及TCP实现可靠传输的机制
关于TCP三次握手和四次挥手大家都在<计算机网络>课程里学过,还记得当时高超老师耐心地讲解.大学里我遇到的最好的老师大概就是这位了,虽然他只给我讲过<java程序设计>和< ...
- 网络通信 --> TCP三次握手和四次挥手
TCP三次握手和四次挥手 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 一.TCP报文格式 如下图: (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发 ...
- TCP 三次握手,四次挥手
TCP 三次握手,四次挥手 1. TCP 三次握手 建立连接前,客户端和服务端需要通过握手来确认对方: 客户端发送 syn(同步序列编号) 请求,进入 syn_send 状态,等待确认 服务端接收并确 ...
- 应聘复习基础笔记1:网络编程之TCP与UDP的优缺点,TCP三次握手、四次挥手、传输窗口控制、存在问题
重要性:必考 一.TCP与UDP的优缺点 ①TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供 ...
- 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手
.引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方 ...
- 网络协议-网络分层、TCP/UDP、TCP三次握手和四次挥手
网络的五层划分是什么? 应用层,常见协议:HTTP.FTP 传输层,常见协议:TCP.UDP 网络层,常见协议:IP 链路层 物理层 TCP 和 UDP 的区别是什么 TCP/UDP 都属于传输层的协 ...
- [转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手
脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手 http://www.52im.net/thread-1729-1-1.html 1.引言 网络编程中TCP协议的三次握手和 ...
随机推荐
- 洛谷P2486 [SDOI2011]染色(树链剖分+线段树判断边界)
[题目链接] [思路]: 涉及到树上区间修改操作,所以使用树链剖分,涉及到区间查询,所以使用线段树. update操作时,就正常操作,难点在于query操作的计数. 因为树链剖分的dfs序只能保证一条 ...
- 05-C#笔记-基本变量
1. 不支持括号初始化: 2. 支持强制类型转化: 3.运算规则同C++ 参考: http://www.runoob.com/csharp/csharp-variables.html
- MySQL体系结构与存储引擎
MySQL 体系结构 先看 MySQL 数据库的体系结构,如下图所示. MySQL 体系结构由 Client Connectors 层.MySQL Server 层及存储引擎层组成. Client C ...
- ActiveMQ 入门和与 Spring 整合
ActiveMQ 入门演示 activemq 依赖 <dependency> <groupId>org.apache.activemq</groupId> < ...
- luogu p2622关灯问题II
luogu p2622关灯问题II 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[ ...
- 【LG2605】[ZJOI2010]基站选址
[LG2605][ZJOI2010]基站选址 题面 洛谷 题解 先考虑一下暴力怎么写,设\(f_{i,j}\)表示当前\(dp\)到\(i\),且强制选\(i\),目前共放置\(j\)个的方案数. 那 ...
- C程序获取命令行参数
命令行参数 命令行界面中,可执行文件可以在键入命令的同一行中获取参数用于具体的执行命令.无论是Python.Java还是C等等,这些语言都能够获取命令行参数(Command-line argument ...
- java 动态数组
package testjavapro; import java.util.*; public class testjava { public static void main(String args ...
- bat脚本清理15天前文件
@echo offset max_days=15 set log_path="D:\backup_new" forfiles /p %log_path% /s /m *.* /d ...
- MOT19数据集百度云盘
图片按视频分的压缩包 [已失效] 链接: https://pan.baidu.com/s/1kNw6yhvqgitNK5N__WOpxw 提取码: yia4 链接: https://pan.baidu ...