Python基础(13)——网络编程入门

基于传输层协议的套接字编程

套接字这个词对很多不了解网络编程的人来说显得非常晦涩和陌生,其实说得通俗点,套接字就是一套用C语言写成的应用程序开发库,主要用于实现进程间通信和网络编程,在网络应用开发中被广泛使用。在Python中也可以基于套接字来使用传输层提供的传输服务,并基于此开发自己的网络应用。实际开发中使用的套接字可以分为三类:流套接字(TCP套接字)、数据报套接字和原始套接字。

TCP套接字

所谓TCP套接字就是使用TCP协议提供的传输服务来实现网络通信的编程接口。在Python中可以通过创建socket对象并指定type属性为SOCK_STREAM来使用TCP套接字。由于一台主机可能拥有多个IP地址,而且很有可能会配置多个不同的服务,所以作为服务器端的程序,需要在创建套接字对象后将其绑定到指定的IP地址和端口上。这里的端口并不是物理设备而是对IP地址的扩展,用于区分不同的服务,例如我们通常将HTTP服务跟80端口绑定,而MySQL数据库服务默认绑定在3306端口,这样当服务器收到用户请求时就可以根据端口号来确定到底用户请求的是HTTP服务器还是数据库服务器提供的服务。端口的取值范围是0~65535,而1024以下的端口我们通常称之为“著名端口”(留给像FTP、HTTP、SMTP等“著名服务”使用的端口,有的地方也称之为“周知端口”),自定义的服务通常不使用这些端口,除非自定义的是HTTP或FTP这样的著名服务。

TCP提供了可靠地数据传输,主要基于以下机制:

​ 1、可靠通信[数据不传丢也不传错] 滑动窗口机制

​ 2、流量控制(自动调节发送数据的速度

​ 3、拥塞控制(网络拥堵时会降低发送速度)

服务器端程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from socket import socket, AF_INET, SOCK_STREAM, SOCK_DGRAM
from datetime import datetime


def main():
# 1、创建套接字对象,并指定使用哪种传输服务
# AF_INET:IPV4 AF_INET6:IPV6 SOCK_STREAM: TCP SOCK_DGRAM: UDP SOCK_RAW: 原始套接字
server_socket = socket(family=AF_INET, type=SOCK_STREAM)
# 2、绑定IP地址和端口,建议使用 1024 以后的端口
print('正在绑定IP地址和端口......')
server_socket.bind(('10.7.152.89', 9999))
print('服务器绑定IP地址和端口成功')
# 3、启动监听 监听客户端有没有连接到服务器 512:历史经验最佳值
print('正在启动服务器......')
server_socket.listen(512)
print('服务器启动成功')

# 4、等待连接 通过循环等待客户端连接并作出相应处理
while True:
# 阻塞并等待连接
client_socket, addr = server_socket.accept()
print(str(addr) + '连接到了服务器.')

# 5、发送数据
client_socket.send(str(datetime.now()).encode('utf-8'))
# 6、断开连接
client_socket.close()


if __name__ == '__main__':
main()

客户端程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from socket import socket, AF_INET, SOCK_STREAM


def main():
# 1、创建套接字 socket
client_socket = socket(family=AF_INET, type=SOCK_STREAM)
# 2、连接服务器
client_socket.connect(('10.7.152.89', 9999))

# 3、循环发送和接收信息
while True:
info = client_socket.recv(1024).decode('utf-8')
print(info)
# client_socket.close()


if __name__ == '__main__':
main()

UDP套接字

传输层除了有可靠的传输协议TCP之外,还有一种非常轻便的传输协议叫做用户数据报协议,简称UDP。TCP和UDP都是提供端到端传输服务的协议,二者的差别就如同打电话和发短信的区别,后者不对传输的可靠性和可达性做出任何承诺从而避免了TCP中握手和重传的开销,所以在强调性能和而不是数据完整性的场景中(例如传输网络音视频数据),UDP可能是更好的选择。可能大家会注意到一个现象,就是在观看网络视频时,有时会出现卡顿,有时会出现花屏,这无非就是部分数据传丢或传错造成的。