在IDLE中插入电话的问题

时间:2013-11-27 15:10:03

标签: python sockets python-idle python-multithreading

我正在尝试在我自己的机器上设置一个小型套接字通信用于测试目的,但我不断收到错误,如“[Errno 10053]已建立的连接被主机中的软件中止”和“[ Errno 10054]远程主机“

强行关闭现有连接

服务器的代码是

import socket, threading, Queue

class PiConn(threading.Thread, object):

    def __init__(self, input_queue, output_queue):
        threading.Thread.__init__(self)
        self.input_queue = input_queue
        self.output_queue = output_queue
        self.HOST = ''
        self.PORT = 8888
        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, msg:
            print "Binding socket failed, error message: " + msg[1]


    def run(self):
        self.s.listen(5)
        while True:
            try:
                #trying to accept data
                conn, addr = self.s.accept()
                print "Connected to", addr
                data = conn.recv(4096)
                self.input_queue.put(data)
            except Exception as e:
                print e, "when trying to accept data"
                break

            try:
                output = self.output_queue.get(False)              
                self.s.sendall(output)
                print "Sent", output
            except Queue.Empty:
                pass
            except socket.error as e:
                print e, "when trying to send data"


input_queue = Queue.Queue()
output_queue = Queue.Queue()

conn = PiConn(input_queue, output_queue)
conn.start()

while True:
    output_queue.put("This is sent by server")
    try:
        print input_queue.get(False)
    except Queue.Empty:
        pass

客户端的代码是     导入套接字,线程,队列

class GUIConn(threading.Thread, object):

    def __init__(self, input_queue, output_queue):
        threading.Thread.__init__(self)
        self.input_queue = input_queue
        self.output_queue = output_queue
        self.PORT = 8888
        self.PI_IP = "127.0.0.1"


        try:
            #Creates a socket
            self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        except socket.error, msg:
            print 'Socket creating failed, error message:' + str(msg[1])

        self.s.connect((self.PI_IP, self.PORT))

    def run(self):
        while True:
            try:
                #Trying to send data
                output = self.output_queue.get(False)
                self.s.sendall(output)
            except Queue.Empty:
                pass
            except socket.error as e:
                print e

            try:
                #trying to accept data
                data = self.s.recv(4096)
                self.input_queue.put(data)
            except Exception as e:
                print e
                break


input_queue = Queue.Queue()
output_queue = Queue.Queue()

conn = GUIConn(input_queue, output_queue)
conn.start()

while True:
    output_queue.put("This is sent by client")
    try:
        print input_queue.get(False)
    except Queue.Empty:
        pass

要测试它,我启动2个IDLE shell,运行服务器,然后运行客户端。 关于我做错了什么的任何线索?我在套接字上相当新,而且我整天都在苦苦挣扎。

提前致谢!

2 个答案:

答案 0 :(得分:2)

您的初始问题是由IDLE在处理线程时遇到的已知问题引起的。

例如,请参阅herehere

我不知道有任何解决方法。尝试从终端运行代码。

至于您获得的其他错误,如果您发布,我们可以尝试并提供帮助。

答案 1 :(得分:1)

警告,文字大墙,在评论之前阅读所有内容

这个少量的代码存在很多问题

首先,最明显的是“忙”循环将耗尽所有100%的cpu,不仅如此,它还会慢慢耗尽所有ram以及导致你为queue.get设置阻塞是假的

你可以将它设置为True并且它会等到有什么东西,一旦它得到它,它将循环回到顶部并放入另一个"This is sent by client"从而解决繁忙循环和ram使用问题

while True:
    output_queue.put("This is sent by client")
    try:
        print input_queue.get(False) # here
    except Queue.Empty:
        pass

第二,你从服务器回复/发送数据到客户端的方式不是通过主侦听套接字,而是从self.s.accept()返回的套接字

因此服务器中的self.s.sendall(output)应为conn.sendall(output)


第三,在客户端代码中,self.output_queue.get(False)可能会错误地使用Queue.Empty并因此通过使用try和except并最终在阻塞recv中 服务器和客户端都会监听并等待彼此发送内容

第四,self.s.accept()阻塞,在服务器中的一个循环之后,它将等待另一个客户端,而客户端将发送数据然后最终等待一些数据

最后,关于你说的那些错误,我根本无法重现它们,如果我必须猜测,我说这些错误是由你的防火墙造成的,或者服务器没有运行(无法绑定)或其他,请参见此处:No connection could be made because the target machine actively refused it

另外,你可以试试一个不同的端口,可能是这个网站上的前两个例子来检查是否有什么奇怪的问题,如果那些例子不起作用那么你的电脑有问题, https://docs.python.org/release/2.5.2/lib/socket-example.html