文章目录
1. TCP-(Transmission Control Protocol)
1.1 TCP客户端
以下是一个标准的TCP客户端建立流程:
# 导入socket库:
import socket
# 创建一个socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('ip_address', 80))
# 发送数据:
s.send('Hello world!')
# 接收数据:
buffer = []
while True:
# 每次最多接收1k字节:
d = s.recv(1024)
if d:
buffer.append(d)
else:
break
# 关闭连接:
s.close()
【TCP客户端建立流程总结:】
【1】调用socket.socket()
创建一个socket
【2】调用connect()
建立连接
【3】调用send()
发送数据
【4】写下循环,调用recv()
等函数接收数据
【5】调用close()
关闭连接
【值得说明的部分:】
【1】在创建socket时,AF_INET
指定使用IPv4协议,如果要用更先进的IPv6,就指定为AF_INET6
。SOCK_STREAM
指定使用面向流的TCP协议,另外还有:
SOCK_DGRAM = 2 使用不连续不可靠的数据包连接,UDP。
SOCK_RAW = 3 提供原始网络协议存取。
SOCK_RDM = 4 提供可靠的数据包连接。
SOCK_SEQPACKET = 5 提供连续可靠的数据包连接。
SOCK_STREAM = 1 提供面向连接的稳定数据传输,即TCP协议。
【2】在建立连接时,connnect()
函数需要传入一个tuple
,第一个I参数是P地址,第二个参数是端口号。
【3】接收数据时,调用recv(max)
方法,一次最多接收指定的字节数,因此,在一个while
循环中反复接收,直到recv()
返回空数据,表示接收完毕,退出循环。
1.2 TCP服务端
【1】服务器进程首先要绑定一个端口并监听来自其他客户端的连接。如果某个客户端连接过来了,服务器就与该客户端建立Socket连接,随后的通信就靠这个Socket连接了。
【2】此外服务器还需要同时响应多个客户端的请求,所以,每个连接都需要一个新的进程或者新的线程来处理,否则,服务器一次就只能服务一个客户端了。
以下是一个TCP服务端的建立流程:
# 导入socket库:
import socket
# TCP连接的线程
def tcplink(sock, addr):
print('Accept new connection from %s:%s...' % addr)
sock.send(b'Welcome!')
while True:
data = sock.recv(1024)
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
sock.close()
print('Connection from %s:%s closed.' % addr)
# 创建一个socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听端口:
s.bind(('127.0.0.1', 9999))
s.listen(5)
print('Waiting for connection...')
while True:
# 接受一个新连接:
sock, addr = s.accept()
# 创建新线程来处理TCP连接:
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
【TCP服务端总结:】
【1】与客户端一样,调用socket.socket()
创建一个socket
【2】调用bind()
函数绑定监听端口,传入的是一个tuple
,第一个参数是服务器地址,第二个参数是端口号
【3】调用listen()
开始监听端口,参数是等待连接的最大数量
【4】进入死循环,调用accept()
接受一个新连接
【5】每接受一个新连接为这个链接创建一个新线程,并调用start()
开启这个线程
【6】在线程中调用send()
发送数据,recv()
接收数据,最后调用close()
关闭这个socket
2. UDP(User Datagram Protocol)
TCP是建立可靠连接,并且通信双方都可以以流的形式发送数据。相对TCP,UDP则是面向无连接的协议。
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。
虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。
2.1 UDP客户端
# 导入socket库:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', b'Tracy', b'Sarah']:
# 发送数据:
s.sendto(data, ('127.0.0.1', 9999))
# 接收数据:
print(s.recv(1024).decode('utf-8'))
s.close()
【UDP客户端总结:】
【1】调用socket.socket()
创建一个socket
,其中SOCK_DGRAM
表示使用不连续不可靠的数据包连接
【2】socket
创建完成之后,直接调用sendto()
发送数据,其中第一个参数是要发送的数据,第二个参数是一个tuple
,传入的是地址和端口号
【3】发送完毕之后仍然采用recv()
接收数据
2.2 UDP服务端
# 导入socket库:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口:
s.bind(('127.0.0.1', 9999))
print('Bind UDP on 9999...')
while True:
# 接收数据:
data, addr = s.recvfrom(1024)
print('Received from %s:%s.' % addr)
s.sendto(b'Hello, %s!' % data, addr)
【UDP服务端总结:】
【1】调用socket.socket()
创建一个socket
,其中SOCK_DGRAM
表示使用不连续不可靠的数据包连接
【2】调用bind()
绑定端口
【3】直接调用recvfrom()
接收数据,该函数返回数据及其地址
【4】根据接收到的地址信息,通过sendto()
向客户端返回数据