簡體   English   中英

如何使用線程“生成”多個TCP客戶端而不是打開多個終端實例並多次運行腳本?

[英]How “generate ” multiple TCP clients using Threads instead of opening multiple instances of the terminal and run the script several times?

我為一個簡單的TCP客戶端編寫了代碼:

from socket import *

# Configurações de conexão do servidor
# O nome do servidor pode ser o endereço de
# IP ou o domínio (ola.python.net)
serverHost = 'localhost'#ip do servidor
serverPort = 50008

# Mensagem a ser mandada codificada em bytes
menssagem = [b'Ola mundo da internet!']

# Criamos o socket e o conectamos ao servidor
sockobj = socket(AF_INET, SOCK_STREAM)
sockobj.connect((serverHost, serverPort))

# Mandamos a menssagem linha por linha
for linha in menssagem:
    sockobj.send(linha)

    # Depois de mandar uma linha esperamos uma resposta
    # do servidor
    data = sockobj.recv(1024)
    print('Cliente recebeu:', data)

# Fechamos a conexão
sockobj.close()

我想知道,如何使用線程“生成”多個客戶端TCP,而不是打開多個終端實例並多次運行腳本。

試試這個:worker方法將被設置為線程的目標。 所以每個線程都會使用該方法的代碼。 啟動所有線程后,底部的for循環將等待所有線程完成。

在worker方法中,您可以使用方法外部的數組或數據列表。 因此,您可以在Urls列表上進行迭代,或者將獲取的數據附加到新的輸出數組。

import threading

threads = []
maxNrOfThreads = 5

def worker():
    do_stuff()

for _ in range(maxNrOfThreads):
    thr = threading.Thread(target=worker)
    threads.append(thr)
    thr.setDaemon(True)
    thr.start()

for thread in threads:
    thread.join()

我剛把你的代碼/你想做的事情包裝成一個函數,即worker() 接下來,我為thread添加了額外的代碼,並將worker()函數設置為target (每個生成的線程將執行的函數/ work / code - 這就是為什么將它命名為worker的慣例)。

th = threading.Thread(target=worker)

上面示例的多線程版本可以如下所示:

import threading
from socket import *

serverHost = 'localhost'#ip do servidor
serverPort = 50008

threads = []
input = input("Enter the number of threads:")
num_of_threads = int(input)

def worker():
    # Criamos o socket e o conectamos ao servidor
    sockobj = socket(AF_INET, SOCK_STREAM)
    sockobj.connect((serverHost, serverPort))

    # Mandamos a menssagem linha por linha
    for linha in menssagem:
        sockobj.send(linha)
        # Depois de mandar uma linha esperamos uma resposta
        # do servidor
        data = sockobj.recv(1024)
        print('Cliente recebeu:', data)

    sockobj.close()

# thread generation block
for t in range(num_of_threads):
    th = threading.Thread(target=worker)
    threads.append(th)
    th.setDaemon(True)
    th.start()

for thread in threads:
    thread.join()

這是一個有隊列發送不同消息的解決方案。

#!/usr/bin/python

import Queue
import threading
import time
from socket import *


DEF_HOST = 'localhost'
DEF_PORT = 50008


queueLock = threading.Lock()


class myThreadTCP (threading.Thread):

    def __init__(self, host=DEF_HOST, port=DEF_PORT, q=None):
        threading.Thread.__init__(self)
        self.host = host
        self.port = port
        self.q = q

    def run(self):
        global queueLock
        print("Starting Thread")
        # Criamos o socket e o conectamos ao servidor
        sockobj = socket(AF_INET, SOCK_STREAM)
        sockobj.connect((self.host, self.port))
        while not workQueue.empty():
            with queueLock:
                data = q.get()
            if data:
                print("sending %s" % data)
                sockobj.send(data)
                # Depois de mandar uma linha esperamos uma resposta
                # do servidor
                data = sockobj.recv(1024)
                print('Cliente recebeu:', data)
        # Fechamos a conexão
        sockobj.close()
        print("Exiting Thread")


workQueue = Queue.Queue()

# Mensagem a ser mandada codificada em bytes
menssagem = [b'Ola mundo da internet!', b'Ola mundo da internet #2!']
for msg in menssagem:
    workQueue.put(msg)

threads = []

# Create 10 new threads
for i in range(0, 10):
    thread = myThreadTCP(host=DEF_HOST, port=DEF_PORT, q=workQueue)
    thread.daemon = True
    thread.start()
    threads.append(thread)

# Wait for all threads to complete
for t in threads:
    t.join()
print("Exiting Main Thread")

最簡單,最pythonic的方法是使用多處理線程池實現 ,然后調用pool.map 前者將允許您在需要時毫不費力地從線程交換到進程。 后者將為您提供一個干凈的界面,隱藏后台的同步事務。

#!/usr/bin/env python3 


import socket
from pprint import pprint
from contextlib import closing
from multiprocessing.dummy import Pool as ThreadPool


serverHost = 'localhost'
serverPort = 80


messageGroups = [
    [b'GET / HTTP/1.0\n\n'],
    [b'GET /some-path HTTP/1.0\n\n'],
]

def send(messages):
    result = []
    options = socket.AF_INET, socket.SOCK_STREAM
    with closing(socket.socket(*options)) as sockobj:
        sockobj.connect((serverHost, serverPort))
        for message in messages:
            sockobj.send(message)
            response = sockobj.recv(1014)
            result.append((message, response))

    return result


if __name__ == '__main__':
    size = 10
    pool = ThreadPool(size)
    result = pool.map(send, messageGroups)
    pool.close()
    pool.join()

    pprint(result)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM