Search code examples
pythonpython-2.7socketsrecvfrom

recvfrom() behaviour when multiple connections to socket


I've been mucking around with a program that sends packets to other copies of itself, and recvfrom has been behaving in a way I don't fully understand. Each instance of the program is set up on a different port (with knowledge of other instances' port numbers already stored in the dictMap dictionary). The idea is that after I've started up a number of instances of this program (say, 8), they should all be pinging each other 3 times a second (MINI_UPDATE_INTERVAL).

However, if I close one of the instances while a whole bunch are running, the programs all keep printing 'ugly disconnect detected etc.' multiple times, even though the instance disconnected has only disconnected once. What's the reason behind this? A portion of my code is below:

PORT = int(args.port)
socket.setdefaulttimeout(1)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,0)#make udp socket and use it to connect
s.bind(("",PORT))
s.setblocking(False)


#timing considerations
STARTTIME = time.time()
prevsent = STARTTIME


print "Node started..."
while True:

    readable, writable, err = select.select([s],[s],[s]) #using select to poll our socket to see if it is readable

    for sock in writable:#if s is writable (it should be), there are packets in the send queue AND one of the next two conditions is met:
        if forwardQueue:
            msgArr = forwardQueue.pop(0)
            sock.sendto(msgArr[MSG],("127.0.0.1",int(msgArr[DESTPORT])))


    for sock in readable: #if there's something to be read...
        try:
            recvMsg, addr = sock.recvfrom(2048)
        except:
            print "ugly disconnect detected" + str(addr[1]) + recvMsg
            break



    for sock in err:
        print "ERROR"



    if time.time() - MINI_UPDATE_INTERVAL > prevsent: #once a second
        # print time.time() - STARTTIME

        for key,value in dictMap.iteritems():
            forwardQueue.append([('PING'+ '|'+idName+'|'+str(time.time())),value])

EDIT: The problem seems to only occur on windows (where WSAECONNRESET constantly keeps popping up after a disconnect). Since my code is ultimately destined for linux I guess it's no big deal.


Solution

  • I believe that you will get your error each time you try to send a packet to a port on a host where nothing is listening on that port (or the listen backlog is full).

    I suggest removing the entry from dictMap in the exception handler to stop additional exceptions from being thrown, since you now know nothing is there.