Python中的底层网络接口(套接字)
Python 标准库中的 'socket' 模块定义了服务器和客户端机器如何使用操作系统上的套接字端点进行通信。'socket' API 包含用于面向连接和无连接网络协议的函数。
套接字是双向通信链路的一个端点。它由 IP 地址和端口号来表征。在任一端正确配置套接字对于启动连接至关重要。这使得在客户端-服务器环境中监听传入消息并发送响应成为可能。
'socket' 模块中的 socket() 函数设置套接字对象。
import socket obj = socket.socket(family, type, protocol)
'family' 参数默认为 AF_INET。其他可接受的值包括:AF_INET6、AF_UNIX、AF_CAN 或 AF_RDS。'type' 参数的值默认为 'SOCK_STREAM',表示面向连接的协议(TCP)。对于无连接协议(UDP),将其设置为 'SOCK_DGRAM'。'protocol' 参数通常默认为 0。
服务器和客户端上的套接字对象分别称为服务器套接字和客户端套接字。套接字对象实现了以下方法
bind() | 此方法将套接字绑定到指定的 IP 地址和端口号。 |
listen() | 此方法启动服务器并进入监听循环,等待来自客户端的连接请求。 |
accept() | 当服务器拦截连接请求时,此方法接受它并使用其地址识别客户端套接字。 |
典型的服务器端代码如下
import socket ss = socket.socket() ss.bind(('localhost',12345)) ss.listen() client, addr = ss.accept() print ("connection request from: " + str(addr))
如果本地机器用作服务器以监听来自同一机器作为客户端的传入消息,则其 IP 地址为 '127.0.0.1',也称为环回地址。它由主机名 'localhost' 识别。套接字被设置为监听任意空闲端口号。对于网络中远程机器之间的通信,必须使用实际的 IP 地址。
客户端套接字向其 IP 地址和端口号处监听的服务器套接字发送连接请求
connect()
obj = socket.socket() obj.connect((host,port))
一旦服务器接受了来自客户端的连接请求,这两个套接字对象现在就使用 TCP 协议连接,并且它们可以发送和/或接收数据。
send()
服务器使用它已拦截的地址向客户端发送数据。
client.send(bytes)
客户端套接字向其已建立连接的套接字发送数据。
obj.send(bytes)
sendall()
类似于 send()。此方法持续发送数据,直到所有数据都发送完毕。
sendto()
此方法仅在 UDP 协议的情况下使用。
recv()
此方法用于检索发送到客户端的数据。在服务器的情况下,它使用已接受请求的远程套接字。
client.recv(bytes)
在客户端的情况下,
obj.recv(bytes)
recvfrom()
此方法在 UDP 协议的情况下使用。
服务器代码
import socket host = "127.0.0.1" port = 12345 ss = socket.socket() ss.bind((host,port)) ss.listen() cs, addr = server.accept() print ("Connection from: " + str(addr)) while True: data = cs.recv(1024).decode() if not data: break print ("from connected user: " + str(data)) print ("Received from User: " + str(data)) data = input("type message: ") conn.send(data.encode()) cs.close()
客户端代码
import socket host = '127.0.0.1' port = 12345 obj = socket.socket() obj.connect((host,port)) message = input("type message: ") while message != 'q': obj.send(message.encode()) data = obj.recv(1024).decode() print ('Received from server: ' + data) message = input("type message: ") obj.close()
打开两个命令提示符窗口。在一个窗口中先运行服务器代码。在另一个窗口中运行客户端代码。