Fatih Arslan
Fatih Arslan

Reputation: 17137

Prevent connected socket from closing in Python

I have simple function that act like a client. It sents an event message and wait for an ack(I removed that part for simplicity). After that it'll get receive more messages:

def send_data(message):
    """Connect to server and get requests"""
    sock = socket.socket()
    host = 'localhost'
    port = 8000
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host,port))

    try:
        if message:
            sock.sendall(message)

        # Look for the response
        has_request = False
        while not has_request:
            data = sock.recv(1024)

            #First I get ACK, code not listed here...
            #Next iteration, I got my request message
            has_request = True

    finally:
        print >> sys.stderr, 'Closing socket'
        sock.close() 

    return data

I call this in the __main__ statement:

if __name__ == '__main__':
    server_data = send_data(event)

    if server_data:
        parse_request(server_data)

However I need to prevent the socket to be closed automatically. Because I have to sent another messagea after I parsed the request. I removed the sock.close() but the socket still get closed. Is this because I'm returing the data and I'm out of the functions scope?

I just want to connect, and then receive and sent messages without any problems, at any time in my program.

Upvotes: 3

Views: 3310

Answers (1)

Cédric Julien
Cédric Julien

Reputation: 80831

When you go outside the send_data method, your socket sock will no longer be referenced by anybody, so the garbage collector will do his job and delete the object, that will consequently close the socket (even without the close() call).

If you return the socket object with your data and get it in your main part, the socket will be still referenced and not closed.

def create_socket():
    sock = socket.socket()
    host = 'localhost'
    port = 8000
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host,port))
    return sock

def send_data(message, sock):
    """Get requests"""
    if message:
        sock.sendall(message)

    # Look for the response
    has_request = False
    while not has_request:
        data = sock.recv(1024)

        #First I get ACK, code not listed here...
        #Next iteration, I got my request message
        has_request = True
    return data

if __name__ == '__main__':
    server_sock = create_socket()
    server_data = send_data(event, server_sock)

    if server_data:
        parse_request(server_data, server_sock)

    #no more use of server_socket ? 
    server_sock.close()

Upvotes: 2

Related Questions