【问题标题】:list/array of (multi-threaded) sockets in pythonpython中(多线程)套接字的列表/数组
【发布时间】:2013-11-05 21:30:21
【问题描述】:

我对python有点陌生。我目前正在尝试在程序中制作和使用套接字列表/数组。所以我声明了一个数组如下:

myCSocks = ['CSock1', 'CSock2', 'CSock3', 'CSock4', 'CSock5']

我正在尝试按如下方式使用我的数组元素:

myCSocks[i], addr = serverSocket.accept()
message = myCSocks[i].recv(1024)

我收到以下错误:

Traceback (most recent call last):
  File "./htmlserv_multi.py", line 22, in <module>
    message = myCSocks[i].recv(1024)
AttributeError: 'str' object has no attribute 'recv'

这对我来说很有意义,它是说我的数组元素是字符串类型而不是套接字。所以我明白我的问题是什么,但我不知道如何解决它。我用谷歌搜索了“python 套接字列表”,但没有找到任何东西。任何帮助将不胜感激。谢谢你。

PS:我的最终目标是创建一个非常简单的多线程 TCP Web 服务器(使用 python)

代码:

#! /usr/bin/env python
from socket import *

#does this work?
myCSocks = []

serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(('192.168.1.4',12000))
serverSocket.listen(5)
while True:
  for i in range(0, len(myCSocks)+1):
    myCSocks[i], addr = serverSocket.accept()
  try:
    for i in range(0, len(myCSocks)):
      message = myCSocks[i].recv(1024)
      filename = message.split()[1]
      f = open(filename[1:])
      outputdata = f.read()
      myCSocks[i].send('HTTP/1.1 200 OK\r\n\r\n')
      for p in range(0, len(outputdata)):
        myCSocks[i].send(outputdata[p])
      myCSocks[i].close()
  except IOError:
    connectionSocket.send('HTTP/1.1 404 Bad Request\r\n\r\n')
    connectionSocket.send('<HTML><p>ERROR 404: BAD REQUEST!</p></HTML>')
    serverSocket.close()
    exit()

【问题讨论】:

    标签: python multithreading sockets webserver


    【解决方案1】:

    一个非常简单的 echo TCP (SOCK_STREAM) 服务器演示了如何实现多处理服务器。使用threadPoolExecutor 异步接受连接。

    服务器:

    import socket
    import concurrent.futures
    
    
    def server_instance(addr):
        HOST = addr[0]
        PORT = addr[1]
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.bind((HOST, PORT))
            s.listen()
            conn, addr = s.accept()
            with conn:
                print(f"Linked with: {addr}")
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    conn.sendall(data)
        return f'DONE'
    
    
    addresses = [
        ('127.0.0.1', 65432),
        ('127.0.0.1', 65431),
        ('127.0.0.1', 65433),
        ('127.0.0.1', 65435),
        ('127.0.0.1', 65434),
    ]
    
    
    with concurrent.futures.ThreadPoolExecutor() as executor:
        for address, status in zip(addresses, executor.map(server_instance, addresses)):
            print(f"{address}: {status}")
    

    客户端向服务器发送数据。

    客户:

    import socket
    import sys
    
    HOST = '127.0.0.1'
    
    
    if len(sys.argv) != 3:
        print(f"[*] Usage: python {sys.argv[0]} <PORT> <MESSAGE>")
        sys.exit()
    
    PORT = int(sys.argv[1])
    print(f"PORT SET TO: {PORT}")
    
    MSG = bytes(sys.argv[2], encoding='utf8')
    print(f"MESSAGE SET TO: {MSG}")
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((HOST, PORT))
        s.sendall(MSG)
        data = s.recv(1024)
    
    print(f'[r] {repr(data)}')
    

    f-strings 需要 python3.6 及以上版本

    并发期货需要 python 3.2 及更高版本

    【讨论】:

      【解决方案2】:

      如果 CSock1 是一个已经定义的类,您可以只引用类对象。但是,如果您尝试执行多线程,则有更好的方法:Multithreaded web server in python。如果您只是想使用套接字,我会查看Multi Threaded TCP server in Python(第二个答案最好)。

      【讨论】:

      • 是否可以仅使用“socket”库实现多线程 Web 服务器?我不需要强大的服务器,我只想演示多线程是如何工作的。感谢您最初的回复。
      • 阅读您的编辑。您推荐给我的新链接看起来相当简单,但是它使用了我不知道如何使用的线程库。我现在将研究线程库,看看会发生什么。谢谢
      【解决方案3】:

      在此处查看内置的 socket 模块 (http://docs.python.org/2/library/socket.html)。这允许您创建套接字,以及发送和接收数据,在线文档中有简单的示例。如果您将字符串替换为实际的套接字,您的代码可能会起作用。如果要按名称存储多个套接字,可以使用字典:

      theDict = {}
      theDict['socket1'] = socket.socket()
      

      等等

      【讨论】:

      • 我收到一个新错误。如果我使用 C/C++,我会在堆中初始化一个数组,并在每次建立连接时创建一个新套接字。我不知道如何用 python 做到这一点。有什么建议吗?
      • 错误是什么?如果您发布您的代码和任何相关输出,将会有所帮助。
      • 嘿,我编辑了我的 OP 并包含了代码。我知道这不起作用,因为我的数组被初始化为空。我想弄清楚该怎么做。谢谢。
      猜你喜欢
      • 2013-05-03
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多