Reputation: 51
I am currently trying to make a Python program where two computers connected to different servers can send messages to each other. Below is my code:
Server.py:
import sys
import socket
def main():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('', 11111))
s.listen(1)
while True:
(conn, addr) = s.accept()
while True:
received = conn.recv(1024)
if received == '':
break
else:
print(received.decode())
send_msg = input().replace('b', '').encode()
if send_msg == ' ':
break
else:
conn.sendall(send_msg)
print("sent")
if __name__ == '__main__':
main()
Client.py:
import sys
import socket
import select
def main():
if len(sys.argv) is not 3:
print("usage: %s [ip adress][port] " % sys.argv[0] )
return(-1)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((sys.argv[1], int(sys.argv[2])))
while True:
s_msg = input().replace('b', '').encode('utf-8')
if s_msg == '':
break
else:
s.sendall(s_msg)
r_msg = s.recv(1024)
if r_msg == '':
break
else:
print(r_msg.decode())
if __name__ == '__main__':
main()
When I executed the code by sending a message from server.py, the message was not sent to the client until I try to send a message from the client to the server. Here is the example of the result:
Does anyone know what's wrong with my code?
Please let me know if any extra information is needed. Thank you in advance.
Upvotes: 0
Views: 7812
Reputation: 51
I was able to implement the simple P2P chat program using the code below:
server.py
import sys
import socket
import threading
#TODO: exit program when client ends the connection
def connect(conn):
while True:
received = conn.recv(1024)
if received ==' ':
pass
else:
print(received.decode())
def sendMsg(conn):
while True:
send_msg = input().replace('b', '').encode()
if send_msg == ' ':
pass
else:
conn.sendall(send_msg)
if __name__ == '__main__':
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 11111))
s.listen()
(conn, addr) = s.accept()
thread1 = threading.Thread(target = connect, args = ([conn]))
thread2 = threading.Thread(target = sendMsg, args = ([conn]))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
client.py
import sys
import socket
import threading
#TODO:end connection with 'exit'
def connect(s):
while True:
r_msg = s.recv(1024)
if not r_msg:
break
if r_msg == '':
pass
else:
print(r_msg.decode())
def receive(s):
while True:
s_msg = input().replace('b', '').encode('utf-8')
if s_msg == '':
pass
if s_msg.decode() == 'exit':
print("wan exit")
break
else:
s.sendall(s_msg)
if __name__ == '__main__':
if len(sys.argv) is not 3:
print("usage: %s [ip adress][port] " % sys.argv[0] )
sys.exit(0)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((sys.argv[1], int(sys.argv[2])))
thread1 = threading.Thread(target = connect, args = ([s]))
thread2 = threading.Thread(target = receive, args = ([s]))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
Upvotes: 1
Reputation: 168
In your code, input()
is a blocking function, meaning the execution stop until you press Enter.
So you need to send a message to execute the receive part.
To deal with is issue, you can use non-blocking input functions as mentioned in this question.
Or maybe using multi-threaded code: one thread read the use input and send, the other thread receive and print.
Edit:
The server can't send messages if he receive nothing due to this line:
received = conn.recv(1024)
if the client is still connected and send nothing, the server will wait on this line. So you need to receive one message on server side to access the send part.
You can try to use non-blocking sockets to prevent this behavior.
Upvotes: 0