3

I am writing a client/ server program in Python where, once the client and server have successfully connected via a socket, they may exchange messages. Below is my server and client code. When compiled, the connection is established correctly and the messages are sent successfully, but one cannot send a second message until it has received a response from the other party.

For example:

Client sends: "Hello, server!"

Server sends: "I have received your message, client!"

Client sends: "great, here's another one"

Client sends: "and a second one!"

At this point, the server terminal window has received the message saying "great, here's another one", but must first reply to this message before receiving "and a second one!". I think my issue is that I need to use the select() method, but do not understand how to do so. How can I fix this?

#The server code

HOST = '' 
PORT = 9999

s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
print("Now listening...")
s.listen(1) #only needs to receive one connection (the client)
conn, addr = s.accept() #accepts the connection
print("Connected by: ", addr) #prints the connection
i = True

while i is True:
    data = conn.recv(1024) #receives data
    print('Received:' , repr(data)) #prints the message from client 
    
    reply = raw_input() #server types a response
    conn.sendall(reply) #server now sends response back to client
    
close()

below is the client code (client.py)

The client code

from socket import*

HOST = '192.168.41.1'
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))

while True:
    message = raw_input()  #client's message to the server
    s.send(message) #sends message to the server
    print("Waiting for response...") 
    reply = s.recv(1024) #receives message from server
    print("New message: " + repr(reply)) #prints the message received 

close()
Community
  • 1
  • 1
Kramsiv1994
  • 41
  • 1
  • 1
  • 4

2 Answers2

3

Look at the following examples: http://code.activestate.com/recipes/531824-chat-server-client-using-selectselect/

and http://www.binarytides.com/code-chat-application-server-client-sockets-python/

also some similar answer here: Python client side in chat

What you are missing is select on client side where its select if to handle input from server or from command line.

So in that case, you don't have to wait for server response and can send 2 calls one after another from the client.

Freely adapting the answers above to what you wished to accomplish. (I didn't test it - so make sure to check it)

from socket import*
import sys
import select

HOST = '192.168.41.1'
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))

while True:
    socket_list = [sys.stdin, s]

    # Get the list sockets which are readable
    read_sockets, write_sockets, error_sockets = select.select(
        socket_list, [], [])

    for sock in read_sockets:
        #incoming message from remote server
        if sock == s:
            data = sock.recv(1024)
            if not data:
                print('\nDisconnected from server')
                break
            else:
                #print data
                sys.stdout.write(data)
                # prints the message received
                print("New message: " + repr(data))
                prompt()
        #user entered a message
        else:
            msg = sys.stdin.readline()
            s.send(msg)
            prompt()

s.close()
Dudi Levy
  • 137
  • 1
  • 4
2

I would strongly suggest reading and familiarizing with this document and especially the non-blocking sockets part.

Your code now blocks when waiting for the data to arrive from the user. You want to instruct your program to wait for the data from the socket and at the same time allow user to type input.

Brent
  • 1,195
  • 10
  • 9
jpou
  • 1,935
  • 2
  • 21
  • 30