【转】Python学习---Socket通信原理以及三次握手和四次挥手详解
【原文】https://www.toutiao.com/i6566024355082404365/
什么是Socket?
Socket的中文翻译过来就是“套接字”。套接字是什么,我们先来看看它的英文含义:插座。
Socket就像一个电话插座,负责连通两端的电话,进行点对点通信,让电话可以进行通信,端口就像插座上的孔,端口不能同时被其他进程占用。而我们建立连接就像把插头插在这个插座上,创建一个Socket实例开始监听后,这个电话插座就时刻监听着消息的传入,谁拨通我这个“IP地址和端口”,我就接通谁。
实际上,Socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口,供应用层调用实现进程在网络中的通信。Socket起源于UNIX,在Unix一切皆文件的思想下,进程间通信就被冠名为文件描述符(file desciptor),Socket是一种“打开—读/写—关闭”模式的实现,服务器和客户端各自维护一个“文件”,在建立连接打开后,可以向文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。
另外我们经常说到的Socket所在位置如下图:
Socket通信过程
Socket保证了不同计算机之间的通信,也就是网络通信。对于网站,通信模型是服务器与客户端之间的通信。两端都建立了一个Socket对象,然后通过Socket对象对数据进行传输。通常服务器处于一个无限循环,等待客户端的连接。
一图胜千言,下面是面向连接的TCP时序图:
客户端过程:
客户端的过程比较简单,创建Socket,连接服务器,将Socket与远程主机连接(注意:只有TCP才有“连接”的概念,一些Socket比如UDP、ICMP和ARP没有“连接”的概念),发送数据,读取响应数据,直到数据交换完毕,关闭连接,结束TCP对话。
import socket
import sys
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建Socket连接
sock.connect(('127.0.0.1', 8001)) # 连接服务器
while True:
data = input('Please input data:')
if not data:
break
try:
sock.sendall(data)
except socket.error as e:
print('Send Failed...', e)
sys.exit(0)
print('Send Successfully')
res = sock.recv(4096) # 获取服务器返回的数据,还可以用recvfrom()、recv_into()等
print(res)
sock.close()
sock.sendall(data)
这里也可用send()方法:不同在于sendall()在返回前会尝试发送所有数据,并且成功时返回None,而send()则返回发送的字节数量,失败时都抛出异常。
服务端过程:
咱再来聊聊服务端的过程,服务端先初始化Socket,建立流式套接字,与本机地址及端口进行绑定,然后通知TCP,准备好接收连接,调用accept()阻塞,等待来自客户端的连接。如果这时客户端与服务器建立了连接,客户端发送数据请求,服务器接收请求并处理请求,然后把响应数据发送给客户端,客户端读取数据,直到数据交换完毕。最后关闭连接,交互结束。
import socket
import sys
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建Socket连接(TCP)
print('Socket Created')
try:
sock.bind(('127.0.0.1', 8001)) # 配置Socket,绑定IP地址和端口号
except socket.error as e:
print('Bind Failed...', e)
sys.exit(0)
sock.listen(5) # 设置最大允许连接数,各连接和Server的通信遵循FIFO原则
while True: # 循环轮询Socket状态,等待访问
conn, addr = sock.accept()
try:
conn.settimeout(10) # 获得一个连接,然后开始循环处理这个连接发送的信息
# 如果要同时处理多个连接,则下面的语句块应该用多线程来处理
while True:
data = conn.recv(1024)
print('Get value ' + data, end='')
if not data:
print('Exit Server', end='')
break
conn.sendall('OK') # 返回数据
except socket.timeout: # 建立连接后,该连接在设定的时间内没有数据发来,就会引发超时
print('Time out')
conn.close() # 当一个连接监听循环退出后,连接可以关掉
sock.close()
conn, addr = sock.accept()
调用accept()时,Socket会进入“waiting”状态。客户请求连接时,方法建立连接并返回服务器。accept()返回一个含有两个元素的元组(conn, addr)。第一个元素conn是新的Socket对象,服务器必须通过它与客户通信;第二个元素addr是客户的IP地址及端口。
data = conn.recv(1024)
接下来是处理阶段,服务器和客户端通过send()和recv()通信(传输数据)。
服务器调用send(),并采用字符串形式向客户发送信息,send()返回已发送的字符个数。
服务器调用recv()从客户接收信息。调用recv()时,服务器必须指定一个整数,它对应于可通过本次方法调用来接收的最大数据量。recv()在接收数据时会进入“blocked”状态,最后返回一个字符串,用它表示收到的数据。如果发送的数据量超过了recv()所允许的,数据会被截短。多余的数据将缓冲于接收端,以后调用recv()时,多余的数据会从缓冲区删除(以及自上次调用recv()以来,客户可能发送的其它任何数据)。传输结束,服务器调用Socket的close()关闭连接。
TCP三次握手的Socket过程:
- 服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待;
- 客户端Socket对象调用connect()向服务器发送了一个SYN并阻塞;
- 服务器完成了第一次握手,即发送SYN和ACK应答;
- 客户端收到服务端发送的应答之后,从connect()返回,再发送一个ACK给服务器;
- 服务器Socket对象接收客户端第三次握手ACK确认,此时服务端从accept()返回,建立连接。
接下来就是两个端的连接对象互相收发数据。
TCP四次挥手的Socket过程:
- 某个应用进程调用close()主动关闭,发送一个FIN;
- 另一端接收到FIN后被动执行关闭,并发送ACK确认;
- 之后被动执行关闭的应用进程调用close()关闭Socket,并也发送一个FIN;
- 接收到这个FIN的一端向另一端ACK确认。
上面的代码是简单的演示Socket的基本函数使用,其实不管有多复杂的网络程序,这些基本函数都会用到。上面的服务端代码只有处理完一个客户端请求才会去处理下一个客户端的请求,这样的服务器处理能力很弱,而实际中服务器都需要有并发处理能力,为了达到并发处理,服务器就需要fork一个新的进程或者线程去处理请求。
【转】Python学习---Socket通信原理以及三次握手和四次挥手详解的更多相关文章
- TCP三次握手与四次挥手详解
目录 TCP三次握手与四次挥手详解 1.TCP报文格式 2.TCP三次握手 3.TCP四次挥手 4.为什么建立连接需要三次握手? 5.为什么断开连接需要四次挥手? 6.为什么TIME_WAIT状态还需 ...
- TCP三次握手与四次挥手详解(最全面)
目录 TCP的三次握手与四次挥手 TCP报文段的首部格式 TCP的工作原理 TCP 的流量控制 TCP的拥塞控制 拥塞控制与流量控制的关系 拥塞控制所起的作用 慢开始和拥塞避免 慢开始算法的原理 三次 ...
- [ 转载 ] Tcp三次握手和四次挥手详解
#TCP的报头: 源端口号:表示发送端端口号,字段长为16位.目标端口号:表示接收端口号,字段长为16位.序列号:表示发送数据的位置,字段长为32位.每发送一次数据,就累加一次该数据字节数的大小.注意 ...
- TCP的三次握手与四次挥手详解
TCP的三次握手与四次挥手是TCP创建连接和关闭连接的核心流程,我们就从一个TCP结构图开始探究中的奥秘 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序 ...
- TCP协议三次握手与四次挥手详解
在计算机网络的学习中TCPi协议与Http协议是我们必须掌握的内容,其中Tcp协议属于传输层,而Http协议属于应用层,本博客主要讲解Tcp协议中的三次握手与四次挥手,关于Http协议感兴趣的可以参看 ...
- 转 TCP/IP的三次握手与四次挥手详解
TCP((Transmission Control Protocol)传输控制协议,是一个面向连接的协议.在运用此协议进行数据传输前都会进行连接的建立工作(三次握手):当数据传输完毕,连接的双方都会通 ...
- TCP/IP的三次握手与四次挥手详解
TCP((Transmission Control Protocol)传输控制协议,是一个面向连接的协议.在运用此协议进行数据传输前都会进行连接的建立工作(三次握手):当数据传输完毕,连接的双方都会通 ...
- TCP三次握手、四次挥手详解
1.TCP报文格式 TCP(Transmission Control Protocol) 传输控制协议.TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接. 我们需要 ...
- TCP三次握手和四次挥手详解
背景描述通过上一篇中网络模型中的IP层的介绍,我们知道网络层,可以实现两个主机之间的通信.但是这并不具体,因为,真正进行通信的实体是在主机中的进程,是一个主机中的一个进程与另外一个主机中的一个进程在交 ...
随机推荐
- C#数据仓储类
https://ninesky.codeplex.com/SourceControl/latest /*============================== 版本:v0.1 创建:2016.2 ...
- Go基础知识
编程基础 Go程序是通过package来组织的(与Python类似) 只有package名称为main的包可以包含main函数 一个可执行程序有且仅有一个main包 一般结构basic_structu ...
- 导入maven项目遇到中文乱码
windows->preferences->content types->word Document 并输入utf-8->update; 右键选中的项目,选择propertie ...
- ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(5)- 创建项目结构
前言 关于理论知识,我的表达能力有限,知识水平有限,就不过多的讲解编程工作中的专用术语了,大家写的代码多了,自然就懂了 前几节课,我们看到了后台的主页面,以及一个自认为比较漂亮的登录界面,算是编程套路 ...
- Java面试题阶段汇总
初级面试题 Java面试题-基础篇一 Java面试题-基础篇二 Java面试题-集合框架篇三 Java面试题-基础篇四 Java面试题-基础篇五 Java面试题-javaweb篇六 Java面试题 ...
- 四种简单的sql语句(增删改查语句)
四种简单的sql语句(增删改查语句) 一.插入语句 insert into [table] ([column],[column],[column]) values(?,?,?) 二.删除语句 dele ...
- Async Await异步调用WebApi
先铺垫一些基础知识 在 .net 4.5中出现了 Async Await关键字,配合之前版本的Task 来使得开发异步程序更为简单易控. 在使用它们之前 我们先关心下 为什么要使用它们.好比 一个 ...
- java队列Queue及阻塞队列
java队列 接口Queue类在java.util包,定义了以下6个方法 详细查看官方文档https://docs.oracle.com/javase/7/docs/api/java/util/Que ...
- 使用ThinkPHP实现分页功能
前几篇(上传,缩略图,验证码,自动验证表单)文章介绍的功能实现都是基于ThinkPHP框架封装好的类进行实现的,所以这次自己写一个分页类在框架中使用. 首先在根目录建一个Tools文件夹,在Tools ...
- cf113D. Museum(期望 高斯消元)
题意 题目链接 Sol 设\(f[i][j]\)表示Petya在\(i\),\(Vasya\)在\(j\)的概率,我们要求的是\(f[i][i]\) 直接列方程高斯消元即可,由于每个状态有两维,因此时 ...