Question

I'm trying to get a small socket communication set up on my own machine for testing purposes, but I keep getting errors like "[Errno 10053] An established connection was aborted by the software in your host machine" and "[Errno 10054] An existing connection was forcibly closed by the remote host"

The code for the server is

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

The code for the client is import socket, threading, Queue

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

To test it, I start 2 IDLE shells, run the server, and then the client. Any clue as to what I'm doing wrong? I'm fairly new at sockets, and I've been struggling with this all day.

Thanks in advance!

Was it helpful?

Solution 2

warning, big wall of text, read all of it before commenting

there is a huge number of problem with this small amount of code

first, the most obvious is the 'busy' loops that will use up all 100% of the cpu, not only that, it will also slowly use up all the ram as well cause you set the blocking for the queue.get to be False

you could have set it to True and it would have waited until there something and once it get that, it would loop back to the top and put another one of "This is sent by client" thus solving both the busy loop and ram usage problem

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


second, the way you reply/send data from the server to the client isn't through the main listening socket but the socket that is return from the self.s.accept()

so self.s.sendall(output) in the server should have been conn.sendall(output)


third, in the client code, there a chance that self.output_queue.get(False) would error with Queue.Empty and thus pass using the try and except and ended up in the blocking recv and both the server and client would both be listening and waiting for each other to send something


fourth, self.s.accept() is blocking, after one loop in the server, it would be stuck waiting for another client while the client would send the data then end up waiting for some data


lastly, about those error you said, i can't reproduce them at all, if i have to guess, i say those error are cause by your firewall or the server isn't running (fail to bind) or something else, see here: No connection could be made because the target machine actively refused it


also, you could try a different port and maybe the first two example on this site to check if there is something weird causing problem, if those example doesn't work then there is a problem with your computer, https://docs.python.org/release/2.5.2/lib/socket-example.html

OTHER TIPS

Your initial problem is caused by known issues IDLE has when working with threads.

See here and here for example.

I'm not aware of any workaround. Try running your code from terminal instead.

As to the other errors you're getting, if you post them, we can try and assist.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top