【问题标题】:Python socket programming with multiple threads具有多线程的 Python 套接字编程
【发布时间】:2015-01-28 20:52:04
【问题描述】:

我正在尝试在 python 中使用套接字。现在,我正试图让它在任何客户端发送任何消息时都被所有客户端接收。但是我得到了非常奇怪的结果。我认为这是因为我正在使用多个线程。每次运行程序时,程序的输出都会发生变化。这是线程问题还是其他问题?

import socket
import sys
from thread import *
from server import Server
from client import Client

s = Server()
start_new_thread(s.acceptConnection,())


m = Client("m")
k = Client("k")
start_new_thread(m.recieveData,())
start_new_thread(k.recieveData,())
k.sendData("Hey!")
print "*"*100
print repr(k.data()), repr(m.data())
print "*"*100
m.sendData("okay okay")
print "*"*100
print repr(k.data()), repr(m.data())
print "*"*100
m.client.close()
k.client.close()
s.s.close()

服务器类:

import socket
import sys
from thread import *

class Server(object):
    def __init__(self,port = 5555):
        self.host = 'localhost'  # '' means connect to all hosts
        self.port = port
        self.text = ""        
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            self.s.bind((self.host, self.port))
        except socket.error as e:
            print(str(e))
        self.s.listen(2)
        print "Waiting for a connection.\n"
        self.connections = []

    def threaded_client(self,conn):
        # conn.send("Connected to server\n")
        while True:
            try:
                data = conn.recv(2048)
            except:
                data = ""
            if(not data):
                break
            # conn.sendall(reply)
            for c,a in self.connections:
                try:
                    c.sendall(data + "\n")
                except:
                    print "connection lost\n"
                    self.connections.remove((c,a))
        conn.close()

    def acceptConnection(self):
        while True:
            conn, addr = self.s.accept()
            self.connections += [(conn,addr)]
            start_new_thread(self.threaded_client,(conn,))

客户端类:

import socket
import sys
from thread import *

class Client(object):
    def __init__(self,name):
        self.host = 'localhost'
        self.port = 5555
        self.name = name
        self.client= socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
        self.client.connect((self.host,self.port))
        self.text = ""

    def sendData(self,data):
        self.client.send(data)

    def recieveData(self):
        while True:
            try:
                data = self.client.recv(2048)
            except:
                break
            if data:
                self.text = data
        self.client.close()

    def data(self):
        return self.text

    def closeClient(self):
        self.client.close()

【问题讨论】:

  • 输出变化是什么意思?
  • 每次运行程序的输出都和上次不一样
  • 以什么方式?不同的排序,损坏?
  • 嗯,不同之处在于我打印存储在客户端中的数据的主程序中打印语句的输出。有时它们都恰好是空字符串。有时他们中的一些是“嘿!\n”或者有时有些是“好吧好吧\n”。理想情况下,输出应该是两个“嘿!”,然后是两个“好的,好的”,因为这是我将数据发送到服务器的顺序。

标签: python multithreading sockets network-programming


【解决方案1】:

无论如何,当您尝试打印数据时,您无法保证数据已经返回给客户。您应该介绍一些Conditions 并使用wait()notifyAll() 来确保数据到达....要检查我的猜测是否正确,请在您的测试中添加一些sleep()

import time
k.sendData("Hey!")
print "*"*100
time.sleep(200)
print repr(k.data()), repr(m.data())
print "*"*100
m.sendData("okay okay")
print "*"*100
time.sleep(200)
print repr(k.data()), repr(m.data())
print "*"*100

如果可行,您应该使用条件并通知进行测试。

此外,您必须通过Lock() 保护data 访问。

def recieveData(self):

    while True:
        try:
            data = self.client.recv(2048)
        except:
            break
        if data:
            self.l.acquire()
            self.text = data
            self.l.release()
    self.client.close()

def data(self):
    self.l.acquire()
    ret = self.text
    self.l.release()
    return ret

其中客户端的属性l__init__中定义

self.l=threading.Lock()

【讨论】:

  • 睡眠的想法奏效了!如果我在发送数据后睡一秒钟,我会得到所需的结果。谢谢!我对此还有一个问题——在我的服务器和客户端类中,我是否正确关闭了我的服务器和客户端套接字?
  • @meh123 关闭很好,但添加关闭更好。我得睡觉了:)
猜你喜欢
  • 2012-12-08
  • 2013-05-03
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多