简体   繁体   中英

list/array of (multi-threaded) sockets in python

I am kind of new to python. I am currently trying to make and use a list/array of sockets in a program. So I have declared an array as follows:

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

And I am trying to use my array elements as follows:

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

I am getting the following error:

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'

This kind of makes sense to me, it is saying that my array elements are of type String and are not sockets. So I understand what my problem is but I do not know how to remedy it. I have googled "list of sockets python" but did not find anything. Any help will be greatly appreciated. Thank you.

PS: My final objective is to create a very simple multithreaded TCP web server (using python)

CODE:

#! /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()

Have a look at the built-in socket module here ( http://docs.python.org/2/library/socket.html ). This allows you to create sockets, and send and receive data, and there are simple examples in the online documentation. Your code will probably work if you replace the strings with actual sockets. If you want to store several sockets by name, you could use a dictionary:

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

etc.

If CSock1 is a class already defined you can just refer to the class objects. However, if you are trying to do a multi-threaded, there's better ways to do that: Multithreaded web server in python . If you are just trying to use sockets, I'd look at Multi Threaded TCP server in Python (the second answer is best).

A very simple echo TCP ( SOCK_STREAM ) server demonstrating how to implement a multiprocessing server. Makes use of threadPoolExecutor to accept connections asynchronously.

Server:

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}")

A client to send data to server.

Client:

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 require python3.6 and up

concurrent futures require python 3.2 and up

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM