python环境下的tcp网络编程
网络概念
网络是由节点和连线构成,表示诸多对象及其相互联系。在数学上,网络是一种图,一般认为专指加权图。网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类型的实际问题中抽象出来的模型。在计算机领域中,网络是信息传输、接收、共享的虚拟平台,通过它把各个点、面、体的信息联系到一起,从而实现这些资源的共享。
客户端/服务端
1.在计算机中,客户端和服务端的架构模式,区分为硬件模式和软件模式
- 硬件客户端
客户端(Client)或称为用户端,是指与服务器相对应,为客户提供本地服务的程序。除了一些只在本地运行的应用程序之外,一般安装在普通的客户机上,需要与服务端互相配合运行。因特网发展以后,较常用的用户端包括了如万维网使用的网页浏览器,收寄电子邮件时的电子邮件客户端,以及即时通讯的客户端软件等。对于这一类应用程序,需要网络中有相应的服务器和服务程序来提供相应的服务,如数据库服务,电子邮件服务等等,这样在客户机和服务器端,需要建立特定的通信连接,来保证应用程序的正常运行。 - 服务端
服务端是为客户端服务的,服务的内容诸如向客户端提供资源,保存客户端数据。 - 软件客户端/服务端
软件服务器和硬件服务器不同的是:软件服务器是安装在硬件上的一种特殊的软件,可以通 过程序的执行完成数据检索、数据处理、数据存取等等各种特性,再通过网络进行数据的共享通信,完成提供网络数据服务的功能!
IP&PORT
- IP: internet protocal 网络互联协议,中文缩写:网协;英文缩写:IP
- PORT:端口 在通过 IP 地址确定了网络上的某个具体主机之后,具体的数据通信主要是通过工作在计算 机中的软件执行的。
- 计算机中的端口号的范围是 0~65535 之间
端口号根据其使用场景,一般区分为公用端口、动态端口、保留端口
公用端口:0~1023
动态端口:1024~65535
保留端口:一般是 unix 系统中超级用户进程分配保留端口号
协议
协议:英文名称 protocal,是多方协商计议之后得出的约定、规则、规范 (ps:不是强制约定的)
通常情况下为了让工作在网络中的多台计算机之间能友好的完成不同软件的数据的通信,出现了互联网数据传输协议的概念,通过协议的约束,不同地域环境的计算机可以通过网络完 成流畅的正确的数据交互。
计算机网络数据传输协议目前最主流的就是欧洲计算机制造协会联盟,也称为国际标准化组 织 ISO 指定的 OSI/RM 七层网络传输模型。
协议族
协议:通常指代单独的一个协议,协议族通常指代互相关联的一组协议,协议栈指代某一组互 相关联的协议和他们所属的 OSI 模型的层级结构。
- 常见的网络传输协议
协议名称 | 协议描述 |
---|---|
HTTP | 超文本传输协议 |
HTTPS | 提供安全通道的超文本传输协议 |
FTP | 文件传输协议 |
SMTP | 简单邮件传输协议 |
TELNET | 虚拟终端协议 |
SSH | 安全外壳协议 |
POP3 | 邮局协议 ( 版本 3) |
IP | 数据包 交换 协议 |
TCP | 端对端传输协议 |
UDP | 数据广播协议 |
DNS | 域名解析 协议,可以通过 nslookup查看域名解析信息 |
DHCP | 动态主机配置协议 |
PYTHON 传输层网络编程
socket由来
python2.x/python3.x 对于网络编程的支持都是非常友好的,本身支持两部分非常有用 的网络编程方式。
⚫ 传统网络编程
⚫ 非阻塞异步网络编程
底层通过套接字 socket 对象的连接,完成多种协议的网络程序服务端/客户端的开发和数据通信。
socket 最初是为同一主机上的应用程序创建,是的主机上运行的一个程序与另一个程序之 间可以完成数据通信操作,程序也称为进程,就出现了不同进程间进行数据交互的操作,因 为交互的模式不同,所以也一般将程序中的套接字区分为两种
⚫ 面向文件的套接字:通过文件进行数据交互
⚫ 面向网络的套接字:通过网络进行数据交互
python中的套接字
套接字模型对象,为了能明确的表示网络中一台数据交互的主机,需要通过 IP 地址寻址确 定主机位置,通过 PORT 端口号确定主机交互接口
在网络套接字交互过程中,出现了两种类型的套接字模型
⚫ 面向连接的套接字模型
⚫ 面向无连接的套接字模型
面向连接的套接字模型,在进行网络数据传输过程中,首先要创建一个连接模型,通过指定 的连接模型进行数据的交互,类似我们生活中拨打电话一样,首先保证通话连接的基础上才 能完成通话内容的交互,比较经典的如 TCP 端对端传输协议就是面向连接的套接字对象
面向无连接的套接字模型,在进行网络数据传输过程中,不需要有效的网络连接模型,在数据传输过程中只负责发送/接受,不保证数据的完整性和实效性;类似我们生活中的广播电台、电视信号等等,操作效率要比面向连接的套接字模型更加高效;比较经典的 UDP 广播 协议使用的就是面向无连接的套接字对象
python 中提供的网络连接套接字,主要包含在 socket 模块中 socket 模块提供了 socket()函数可以完成如上描述的各种网络套接字的构建、通信等操作
⚫ 基本语法结构 socket.socket(socket_family, socket_type, protocal=0) socket_family:socket 地址家族,AF_UNIX/AF_LOCAL 或者 AF_INET socket_type:socket 连接类型 面向连接的(SOCK_STREAM),面向无连接的(SOCK_DGRAME) protocal:传输协议,一般不用设置,使用默认值进行自动匹配就好
⚫ 创建 TCP 协议的套接字 socket 对象
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
⚫ 创建 UDP 协议的套接字 socket 对象
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ocket 套接字常用操作
属性 | 描述 |
---|---|
s.bind() | 绑定(主机名称、端口)到一个套接字上 |
s.listen() | 设置并启动 TCP 监听 |
s.accept() | 等待客户端连接 |
s.connect() | 连接指定服务器 |
s.connect_ex() | 连接指定服务器,如果出现错误返回错误信息 |
s.recv() | 接受 TCP 消息 |
s.recv_into( | 接受 TCP 消息到缓冲区 |
s.send() | 发送 TCP 消息 |
s.sendall() | 完整发送 TCP 消息 |
s.recvfrom() | 接受 UDP 消息 |
s.recvfrom_into() | 接受 UDP 消息到缓冲区 |
s.sendto() | 发送 UDP 消息 |
s.shutdown() | 关闭连接对 |
s.close() | 关闭套接字对 |
TCP编程
TCP:Transmission Control Protocal 传输控制协议 是一种面向连接的,可靠的、基于字节流的传输层通信协议
数据传输的可靠性的处理方式,经典的 TCP 模型中通过如下两种方式完成连接的可靠性
⚫ 三次握手建立连接 ◼
A- > B:发送一个寻址请求码 seq=100;
B->A:返回一个应答 ack=101 ◼
A->B:发送一个确认请求码 seq=101,确认连接;
B->A:返回一个应答 ack=300 ◼
A->B:发送一个连接请求码 ack=300;
B->A:返回应答 ack=80 ◼
A 和 B 之间开始进行数据交互
⚫ 四次挥手断开连接 ◼
A->B:发送一个数据验证请求码 seq=100,
B->A:返回一个应答 ack=101 ◼
A->B:发送一个传输结束标记:seq=101;
B->A:返回一个应答 ack=200 ◼
A->B:发送一个确认结束标记:seq=200;
B->A:返回一个应答 ack=300 ◼
A->B:发送连接断开标记:seq=300;
B->A:返回断开连接应答:ack=400
正是有了三次握手和四次挥手对于连接可靠性的保障,才让 TCP 协议端对端的数据交互变 得可行,但是同样由于该协议的过于可靠,被有心人利用经常实施 DDOS 拒绝服务攻击!
python环境下的TCP服务端开发
"""
tcp服务端开发
version 1.1.0
author lkk
email [email protected]
"""
import socket
# 定义服务端主机信息
HOST = ''
PORT = 8888
ADDRESS = (HOST, PORT)
BUFFER = 1024
# 创建可以操作tcp协议的socket对象
test_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 将socket对象与服务端主机信息进行绑定
test_tcp.bind(ADDRESS)
# 开始监听
print('开始启动服务端')
test_tcp.listen(255)
# 等待客服端的连接
while True:
print('等待客户端连接>>>>')
client_socket, client_addr = test_tcp.accept()
print('客户端:{}连接成功'.format(client_addr))
client_socket.send("欢迎您的使用".encode('gbk'))
while True:
info = client_socket.recv(BUFFER)
msg1 = input('服务端:')
client_socket.send(msg1.encode('gbk'))
try:
print('客户端:{}'.format(info.decode('gbk')))
except:
print('客户端:{}'.format(info.decode('gbk')))
if msg1 == b'bye':
print("客户端:{}退出成功".format(client_addr))
client_socket.close()
break
# 关闭【服务端一般情况下不要求关闭】
tcp_socket.close()
python环境下的TCP客户端开发
"""
tcp客户端开发
version 1.1.0
author lkk
email [email protected]
"""
import socket
HOST = '192.168.11.203'
PORT = 8888
ADDRESS = (HOST, PORT)
BUFFER = 1024
test_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
test_client.connect(ADDRESS)
while True:
info = test_client.recv(BUFFER)
print("服务端:", info.decode("gbk"))
msg1 = input('客户端:')
test_client.send(msg1.encode('gbk'))
# print('客户端:{}'.format())
if msg1 == 'bye':
test_client.close()
break