当前位置: 首页 > 编程笔记 >

在Python中使用多线程进行套接字编程?

齐昊
2023-03-14
本文向大家介绍在Python中使用多线程进行套接字编程?,包括了在Python中使用多线程进行套接字编程?的使用技巧和注意事项,需要的朋友参考一下

多线程概念

多线程是几乎所有现代编程语言(尤其是python)的核心概念,因为它的线程实现简单。

线程是程序内的子程序,可以独立于代码的其他部分执行。线程在同一上下文中执行,以共享程序的可运行资源(如内存)。

当在一个进程中,我们同时执行多个线程时,称为多线程。

用于线程实现的Python多线程模块

为了在程序中实现线程,python提供了两个模块-

  • 线程(对于python 2.x)或_thread(对于python 3.x)模块

  • 穿线模块

线程模块将线程创建为函数,而线程模块提供面向对象的方法来创建线程。

语法

_thread.start_new_thread(func, args[, kwargs])

上面启动了一个新线程并返回其标识符。第一个参数是函数func,线程将使用第二个参数执行该函数,该第二个参数包含具有参数位置列表的元组。可选的kwargs参数指定关键字参数的字典。当函数返回时,线程静默地存在。

在此,我们看到了客户端-服务器应用程序的基本示例。客户端从根本上打开套接字连接并将查询发送到服务器。服务器响应。

在不带任何参数的情况下运行,该程序从一个TCP套接字服务器启动,该服务器侦听端口8000上与127.0.0.1的连接。

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("线程未启动。")
      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

因此,线程提供了一种最常见的技术来处理多个套接字连接和客户端。

 类似资料:
  • 这是我的客户端和服务器的代码。 class Client1{Client1(int no){try{String message;message=“Hello this is client”+no;byte[]b=message.getBytes();DatagramPacket dp=new DatagramPacket(b,b length,inetAddress.getLocalHost()

  • 为了实现这一点,我使用了队列/线程池机制。最初,我创建一个固定数量线程的池,并有一个队列datastructure来存储客户机地址。这个队列在所有线程之间共享,因此我使用“互斥”来锁定/解锁这个队列。在主服务器线程中,我创建一个套接字,将其绑定到全局端口/地址,然后在“recvfrom”调用上阻止服务器。任何希望与服务器通信的客户端都会向侦听全局端口地址的主线程服务器发送“HI”消息。主服务器线程

  • 我是Java和JavaFX的新手,所以请原谅我的新手问题。在过去的几天里,我一直在寻找我正在努力做的事情的例子,但是没有找到任何答案。下面是我正在尝试做的:我试图创建一个简单的javafx GUI客户端套接字应用程序,使用场景生成器连接到服务器并发送/接收数据。很简单,但是当我试图在JavaFX中实现它时,我的图形用户界面冻结了。我研究发现,原因是套接字通信占用了所有的时间,javafx GUI无

  • 先说明我的问题。我已经在这里张贴了另一个类似的问题:PrintStream不能正确打印unicode字符(UTF-16 ),但不知何故我没有设法克服这个问题。 我想从android打印到网络打印机(施乐WC 24 PCL或者爱普生XP-600)。< br >假设: 我有以下文字: 然后我用“ISO-8859-7”、“Windows-1253”(希腊字符)调用以下代码: 但是打印机的结果(在ecli

  • 我有一个类似的问题,但是我知道当我要求阅读一行时,发件人应该发送一个行尾。 让我困惑的是,在调试中,它是有效的。可能是因为我在调试时跳过的顺序(直到现在我都不知道这会有什么不同),但我想更好地理解它。 我已经使用线程,但不是很多。 这是我的服务器类: 线程(基于此) 和客户: 它似乎在某个地方进入了死锁,出于某种原因,除非在调试中运行,否则永远不要在向客户端发送数据的服务器类上输入该死锁 (顺便说

  • 问题内容: 在过去的两年中,我一直在编写Java,现在,我开始用python(另外)进行编写。 问题是,当我查看我的Python代码时,似乎有人试图将Java代码转换为python格式,但结果却很糟糕,因为- python不是Java。 关于如何摆脱“用Python编写Java”模式的任何技巧? 谢谢! 问题答案: 您可能会考虑将自己沉浸在Python范例中。最好的方法是首先了解他们的知识,然后通