9

I am new to socket programming. I wanted to create a simple messaging system between the server and the client ( chat ). I have included my code below. I am expecting it to work as similar as chat system but it doesn't work. If the message is sent it should receive and print it out but only after giving the input the received string is printed. I am expecting it should run parallelly (receive a message and send a message).

Server :

import socket
import time
import threading

def get(s):
    tm = s.recv(1024)
    print("\nReceived: ",tm.decode('ascii'))

def set_(s):
    i=input("\nEnter : ")
    s.send(i.encode('ascii'))

 serversocket = socket.socket()
 host = socket.gethostname()
 port = 9981
 serversocket.bind((host,port))
 serversocket.listen(1)
 clientsocket,addr = serversocket.accept()
 while(1):
    t1=threading.Thread( target = get ,  args = (clientsocket,) )
    t1.start()
    t2=threading.Thread( target = set_ ,  args = (clientsocket,) )
    t2.start()
    time.sleep(10)
clientsocket.close()

Client:

import socket
import threading
import time
def get(s):
    tm = s.recv(1024)
    print("\nReceived: ",tm.decode('ascii'))    

def set_(s):
    i=input("\nEnter : ")
    s.send(i.encode('ascii'))

s = socket.socket()
host = socket.gethostname()
port = 9981
s.connect((host,port))

while(1):
    t1=threading.Thread( target = get ,  args = (s,) )
    t2=threading.Thread( target = set_ , args = (s,) )
    t1.start()
    t2.start()
    time.sleep(10)
s.close()

Output (At Client) :

Enter: hello ------------------------------>(1)

Received: hello --------------------------->(3)

Output (At Server) :

Enter: hello ------------------------------>(2)

Received :  hello ------------------------->(4)

Expected Output:

Output (At Client) :

Enter: hello ------------------------------>(1)

Received: hello --------------------------->(4)

Output (At Server) :

Received :  hello ------------------------->(2)

Enter: hello ------------------------------>(3)

The number represents the order of execution.

2
  • My guess is that, because stdout is line-buffered, and you’re trying to write to it from two different threads, the one that writes a partial line (the input) doesn’t show up until after the one that writes a complete line, or something like that. If you put a \n at the end of the input prompt for testing, what happens? Commented Aug 23, 2018 at 15:51
  • I am getting some sort of output. Commented Aug 24, 2018 at 1:04

1 Answer 1

4

There is an issue with the threading logic of your program. You should move the while(True) loops to the thread workers, and only start your threads once. As it stands, your code can only send/receive one message every 10 seconds.

Server:

import socket
import threading

def get(s):
    while True:
        tm = s.recv(1024)
        print("\nReceived: ",tm.decode('ascii'))

def set_(s):
    while True:
        i=input("\nEnter : ")
        s.send(i.encode('ascii'))

serversocket = socket.socket()
host = socket.gethostname()
port = 9981
serversocket.bind((host,port))
serversocket.listen(1)
clientsocket,addr = serversocket.accept()
t1=threading.Thread( target = get ,  args = (clientsocket,) )
t1.start()
t2=threading.Thread( target = set_ ,  args = (clientsocket,) )
t2.start()

Client:

import socket
import threading

def get(s):
    while True:
        tm = s.recv(1024)
        print("\nReceived: ",tm.decode('ascii'))

def set_(s):
    while True:
        i=input("\nEnter : ")
        s.send(i.encode('ascii'))

s = socket.socket()
host = socket.gethostname()
port = 9981
s.connect((host,port))
t1=threading.Thread( target = get ,  args = (s,) )
t2=threading.Thread( target = set_ , args = (s,) )
t1.start()
t2.start()

You'll need to handle closing the sockets differently, and the enter/received prints get out of sync after the first message due to the multithreaded nature of the program, but the input is still waiting.

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

5 Comments

That’s all true (plus the code should be using sendall on one side and recv should append to a buffet that gets split into lines rather than just dumping whatever shows up as a single recv whether it’s half a line or four lines—or they should just use makefile on the sockets), but that doesn’t explain the problem the OP is seeing.
Running the code on my machine produces the desired results from OP. Output (At Client) : Enter: hello(1) Received: hello(4) Output (At Server) : Received : hello(2) Enter: hello(3)
But I am not getting the solution as expected.
Are you running these files in separate instances of Python?
I don't understand what your desired result is. Here is a screenshot of the scripts interacting with order labels. So; 1. Entered 'Hello' on the Server 2. Received 'Hello' on Client 3. Entered 'Hello' on Client 4. Received 'Hello' on Server

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.