Python 多线程套接字编程?
多线程概念
多线程是几乎所有现代编程语言的核心概念,特别是 Python,因为它实现了简单的线程。
线程是程序中的一个子程序,可以独立于代码的其他部分执行。线程在相同的上下文中执行,共享程序的可运行资源,例如内存。
当在单个进程中,我们同时执行多个线程时,这称为多线程。
Python 多线程模块用于线程实现
为了在程序中实现线程,Python 提供了两个模块:
- thread(适用于 Python 2.x)或 _thread(适用于 Python 3.x)模块
- threading 模块
其中 thread 模块将线程创建为函数,而 threading 模块提供了一种面向对象的方法来创建线程。
语法
_thread.start_new_thread(func, args[, kwargs])
以上代码启动了一个新线程并返回其标识符。第一个参数是函数 func,线程使用第二个参数执行,第二个参数包含一个元组,其中包含参数的位置列表。可选的 kwargs 参数指定一个关键字参数字典。当函数返回时,线程会静默退出。
在这里,我们看到了一个客户端-服务器应用程序的基本示例。客户端基本上打开套接字连接并将查询发送到服务器。服务器进行响应。
在没有参数的情况下运行时,此程序将启动一个 TCP 套接字服务器,该服务器侦听 127.0.0.1 上端口 8000 的连接。
client_thread1.py
import socket
import sys
def main():
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "127.0.0.1"
port = 8000
try:
soc.connect((host, port))
except:
print("Connection Error")
sys.exit()
print("Please enter 'quit' to exit")
message = input(" -> ")
while message != 'quit':
soc.sendall(message.encode("utf8"))
if soc.recv(5120).decode("utf8") == "-":
pass # null operation
message = input(" -> ")
soc.send(b'--quit--')
if __name__ == "__main__":
main()而服务器程序是:
server_thread1.py
import socket
import sys
import traceback
from threading import Thread
def main():
start_server()
def start_server():
host = "127.0.0.1"
port = 8000 # arbitrary non-privileged port
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print("Socket created")
try:
soc.bind((host, port))
except:
print("Bind failed. Error : " + str(sys.exc_info()))
sys.exit()
soc.listen(6) # queue up to 6 requests
print("Socket now listening")
# infinite loop- do not reset for every requests
while True:
connection, address = soc.accept()
ip, port = str(address[0]), str(address[1])
print("Connected with " + ip + ":" + port)
try:
Thread(target=client_thread, args=(connection, ip, port)).start()
except:
print("Thread did not start.")
traceback.print_exc()
soc.close()
def clientThread(connection, ip, port, max_buffer_size = 5120):
is_active = True
while is_active:
client_input = receive_input(connection, max_buffer_size)
if "--QUIT--" in client_input:
print("Client is requesting to quit")
connection.close()
print("Connection " + ip + ":" + port + " closed")
is_active = False
else:
print("Processed result: {}".format(client_input))
connection.sendall("-".encode("utf8"))
def receive_input(connection, max_buffer_size):
client_input = connection.recv(max_buffer_size)
client_input_size = sys.getsizeof(client_input)
if client_input_size > max_buffer_size:
print("The input size is greater than expected {}".format(client_input_size))
decoded_input = client_input.decode("utf8").rstrip()
result = process_input(decoded_input)
return result
def process_input(input_str):
print("Processing the input received from client")
return "Hello " + str(input_str).upper()
if __name__ == "__main__":
main()在运行上述脚本时,在终端中运行 server_thread1.py,如下所示:
python server_thread1.py Socket created Socket now listening
我们将观察服务器窗口并了解流程。现在打开多个客户端终端,运行客户端线程
python client_thread1.py Enter 'quit' to exit -> Zack ->
在另一个终端中,运行另一个客户端程序并观察服务器终端窗口:
python client_thread1.py Enter 'quit' to exit -> Python -> quit
另一个终端,运行客户端线程:
python client_thread1.py Enter 'quit' to exit -> world! -> Anothny ->
我们可以看到我们的服务器窗口将显示类似以下内容的输出:
Socket created Socket now listening Connected with 127.0.0.1:50275 Processing the input received from client Processed result: Hello ZACK Connected with 127.0.0.1:50282 Processing the input received from client Processed result: Hello PYTHON Processing the input received from client Client is requesting to quit Connection 127.0.0.1:50282 closed Connected with 127.0.0.1:50285 Processing the input received from client Processed result: Hello WORLD! Processing the input received from client Processed result: Hello ANOTHNY
因此,线程提供了处理多个套接字连接和客户端的最常用技术之一。
广告
数据结构
网络
关系型数据库管理系统
操作系统
Java
iOS
HTML
CSS
Android
Python
C 编程
C++
C#
MongoDB
MySQL
Javascript
PHP