0

So I am very new to networking and the Socket module in Python. So I watched some Youtube tutorials and found one on how to write the code for a simple server. My problem is right when the server receives data from the client, the server close() and loses connection to the client right when it receives the data. I want the server to automatically lose connection to the client but not "shutdown" or close(). I want to set it (if its possible) so that while the server is running in my Python Shell, if I want to close() the connection I use hot keys like for example "Control+E"? Here is my code so far:

#!/usr/bin/python
import socket
import sys

# Create a TCP/IP socket to listen on
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Prevent from "adress already in use" upon server restart
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Bind the socket to port 8081 on all interfaces
server_address = ('localhost',8081)
print ('starting up on %s port %s')%(server_address)
server.bind(server_address)

#Listen for connections
server.listen(5)

#Wait for one incoming connection
connection, client_address = server.accept()
print 'connection from', connection.getpeername()

# Let's recieve something
data = connection.recv(4096)
if data:
    print "Recived ", repr(data)

    #send the data back nicely formatted
    data = data.rstrip()
    connection.send("%s\n%s\n%s\n"%('-'*80, data.center(80),'-'*80))

# lose the connection from our side (the Server side)
connection.shutdown(socket.SHUT_RD | socket.SHUT_WR)
connection.close()
print 'Connection closed'

# And stop listening
server.close()

================================================================================== Here is the code I am using (on the server side):

#!/usr/bin/python

import socket, sys
import select

srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#Let's set the socket option reuse to 1, so that our server terminates quicker
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

srv.bind(("localhost", 8081))
srv.listen(5)

while True:
    print "Waiting for a client to connect"
    (client, c_address) = srv.accept() #blocking wait for client
    print "Client connected"

    # Client has connected, add him to a list which we can poll for data
    client_list = [client]

while close_socket_condition == 0:
    ready_to_read, ready_to_write, in_error = select.select(client_list, [], [] , 1) #timeout 1 second

    for s in ready_to_read: #Check if there is any socket that has data ready for us

        data = client.recv(1024) # blocks until some data is read

    if data:
        client.send("echo:" + data)

    client.close()
    close_socket_condition = 1

And here is the error it is giving me when I try to send a string to the server:

  data = s.recv(1024)
  File "C:\Python27\lib\socket.py", line 170, in _dummy
    raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor
2
  • So if the code executing as intended? is data filled with something ? If you want to keep connections alive, and only exit on certain external event, you will have to look into non-blocking sockets, and also create some kind of message handling loop Commented Jun 10, 2014 at 4:51
  • Yes the data is sent from a client that I made (both are running on my computer btw) and the data is just a string saying "Hello there!" . And hmmmm so is there no way I can simply just lose a connection to a client but keep the server running? Commented Jun 10, 2014 at 4:55

1 Answer 1

1

Here is example on a non-blocking socket read with similar structure as yours.

The server will establish a socket in localhost, and wait for a client to connect. After that it will start polling the socket for data, and also keep checking the exit condition close_socket_condition. Handling ctrl-e or other exit events will be left as an exercise :)

First we start socket, very much the same way as you:

#!/usr/bin/python

import socket, sys
import select

srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#Let's set the socket option reuse to 1, so that our server terminates quicker
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

srv.bind(("localhost", 8081))
srv.listen(5)

Then we declare our external exit condition close_socket_condition, and start eternal while loop that will always welcome new clients:

close_socket_condition = 0

while True:

  print "Waiting for a client to connect"
  (client, c_address) = srv.accept() #blocking wait for client
  print "Client connected"

Now a client has connected, and we should start our service loop:

 # Client has connected, add him to a list which we can poll for data
 client_list = [client]

 while close_socket_condition == 0:

Inside the service loop we will keep polling his socket for data and if nothing has arrived, we check for exit condition:

  ready_to_read, ready_to_write, in_error = select.select(client_list, [], [] , 1) #timeout 1 second

  for s in ready_to_read: #Check if there is any socket that has data ready for us

    data = client.recv(1024) # blocks until some data is read

    if data:
      client.send("echo:" + data)

    client.close()
    close_socket_condition = 1

This code is simplified example, but the server will keep accepting new clients, and always reuse the connection. It does not handle client side terminations etc.

Hope it helps

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! The comments added in with the code really helps, especially because I am new to socket and everything. So I tried running this code and it ran. Then I ran a client but when I tried to send something to the server it gave me an error? I will edit my question and post the error I am getting and my code.
You're welcome. Just take care of some logic what would happen if multiple clients would connect (maybe create separate handler threads?), and if someone would never send data etc. Also there is no general exception handling now..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.