6

This is a python chat room that I've been working on and it enables to you to chat to other people on the same network through python

Host:

import socket
import sys
import time
s = socket.socket()
host = socket.gethostname()
port = 8080
s.bind((host,port))
print("")
print("Sever adress is", host)
print("")
name = input(str("Please enter your username : "))
s.listen(1)
print("")
print("Waiting for any incoming connections ... ")
print("")
conn, addr = s.accept()
print("Recieved connection")
#connection done ###
s_name = conn.recv(1024)
s_name = s_name.decode()
print("")
print(s_name, "has connected to the chat room")
print("")
conn.send(name.encode())
## messaging loop ##
while 1:
 message = input(str("Please enter enter your message : "))
 print("")
 conn.send(message.encode())
 message = conn.recv(1024)
 message = message.decode()
 print("")
 print(name,": ",message)
 print("")

Client:

import socket
import sys
import time
print("Welcome to python chat ")
print("")
print("Initiallsing....")
time.sleep(1)
s = socket.socket()
print("")
host = input(str("Please enter server adress : "))
print("")
name = input(str("Please enter your name : "))
port = 8080
print("")
time.sleep(1)
s.connect((host,port))
print("Connected...")
## Conection done ##
s.send(name.encode())
s_name = s.recv(1024)
s_name = s_name.decode()
print("")
print( s_name, "has joined the chat room ")
while 1:
 message = s.recv(1024)
 message = message.decode()
 print("")
 print(name,": ",message)
 print("")
 message = input(str("Please enter your enter message : "))
 print("")
 s.send(message.encode())

I have 2 problems, the first problem is that it only allows one person to speak at a time, what I mean by this say that if you send a message first you won't be allowed to send another message until the other person has responded. The second problem is that this code only works for 2 users, I want it so it works for multiple users

Edit:

Also could some one acutually give a proper solution instead of telling me to start all over again please because it took me so long to figure out how to make this system in the place.

Thank you

asked Feb 8, 2019 at 19:21
9
  • 1
    You should try Google first. You're more likely to get more in-depth answers. google.com/search?q=python+chat+program+example Commented Feb 8, 2019 at 19:25
  • @JohnnyMopp I have looked at google but I just don't get how to put it into my code Commented Feb 8, 2019 at 19:31
  • You need to create two separate threads for sending and receiving. The way you have written the loop will not work for both way communication simultaneously. Because after sending a message your loop is waiting to receive something. Commented Feb 8, 2019 at 19:45
  • @shariful Could you show me how to do it please Commented Feb 8, 2019 at 19:49
  • I have posted an answer below, please have a look. @system123456 Commented Feb 8, 2019 at 19:52

3 Answers 3

3

You need to create two separate threads for sending and receiving. The way you have written the loop will not work for both way communication simultaneously. Because after sending a message the loop is waiting to receive something. [If you want to run the code over internet, replace localhost with the desired IP address in the line HOST = 'localhost'] Let me share a solution (this is a sample solution I have done while TAing an undergraduate class on networking):

I have tested the code on a Linux machine (Ubuntu 18.04). I have got students who have successfully ran this on their Mac. I am not sure if it runs on a windows machine. Even if it does not work on a Windows machine, a few minor modifications should do the trick.

Server sider code (you need to run this first): chatServerDuplex.py

# Import socket module
from socket import *
import threading
import sys # In order to terminate the program
FLAG = False # this is a flag variable for checking quit
# function for receiving message from client
def recv_from_client(conn):
 global FLAG
 try:
 # Receives the request message from the client
 while True:
 if FLAG == True:
 break
 message = conn.recv(1024).decode()
 # if 'q' is received from the client the server quits
 if message == 'q':
 conn.send('q'.encode())
 print('Closing connection')
 conn.close()
 FLAG = True
 break
 print('Client: ' + message)
 except:
 conn.close()
# function for receiving message from client
def send_to_client(conn):
 global FLAG
 try:
 while True:
 if FLAG == True:
 break
 send_msg = input('')
 # the server can provide 'q' as an input if it wish to quit
 if send_msg == 'q':
 conn.send('q'.encode())
 print('Closing connection')
 conn.close()
 FLAG = True
 break
 conn.send(send_msg.encode())
 except:
 conn.close()
# this is main function
def main():
 threads = []
 global FLAG
 # TODO (1) - define HOST name, this would be an IP address or 'localhost' (1 line)
 HOST = 'localhost'
 # TODO (2) - define PORT number (1 line) (Google, what should be a valid port number)
 # make sure the ports are not used for any other application
 serverPort = 6789
 # Create a TCP server socket
 #(AF_INET is used for IPv4 protocols)
 #(SOCK_STREAM is used for TCP)
 # TODO (3) - CREATE a socket for IPv4 TCP connection (1 line)
 serverSocket = socket(AF_INET, SOCK_STREAM)
 # Bind the socket to server address and server port
 # TODO (4) - bind the socket for HOSR and serverPort (1 line)
 serverSocket.bind((HOST, serverPort))
 # Listen to at most 1 connection at a time
 # TODO (5) - listen and wait for request from client (1 line)
 serverSocket.listen(1)
 # Server should be up and running and listening to the incoming connections
 print('The chat server is ready to connect to a chat client')
 # TODO (6) - accept any connection request from a client (1 line)
 connectionSocket, addr = serverSocket.accept()
 print('Sever is connected with a chat client\n')
 t_rcv = threading.Thread(target=recv_from_client, args=(connectionSocket,))
 t_send = threading.Thread(target=send_to_client, args=(connectionSocket,))
 # call the function to receive message server
 #recv_from_server(clientSocket)
 threads.append(t_rcv)
 threads.append(t_send)
 t_rcv.start()
 t_send.start()
 t_rcv.join()
 t_send.join()
 # closing serverScoket before exiting
 print('EXITING')
 serverSocket.close()
 #Terminate the program after sending the corresponding data
 sys.exit()
# This is where the program starts
if __name__ == '__main__':
 main()

Client side code: chatClientDuplex.py

from socket import *
import threading
import sys
FLAG = False # this is a flag variable for checking quit
# function for receiving message from client
def send_to_server(clsock):
 global FLAG
 while True:
 if FLAG == True:
 break
 send_msg = input('')
 clsock.sendall(send_msg.encode())
# function for receiving message from server
def recv_from_server(clsock):
 global FLAG
 while True:
 data = clsock.recv(1024).decode()
 if data == 'q':
 print('Closing connection')
 FLAG = True
 break
 print('Server: ' + data)
# this is main function
def main():
 threads = []
 # TODO (1) - define HOST name, this would be an IP address or 'localhost' (1 line)
 HOST = 'localhost' # The server's hostname or IP address
 # TODO (2) - define PORT number (1 line) (Google, what should be a valid port number)
 PORT = 6789 # The port used by the server
 # Create a TCP client socket
 #(AF_INET is used for IPv4 protocols)
 #(SOCK_STREAM is used for TCP)
 # TODO (3) - CREATE a socket for IPv4 TCP connection (1 line)
 clientSocket = socket(AF_INET, SOCK_STREAM)
 # request to connect sent to server defined by HOST and PORT
 # TODO (4) - request a connection to the server (1 line)
 clientSocket.connect((HOST, PORT))
 print('Client is connected to a chat sever!\n')
 # call the function to send message to server
 #send_to_server(clientSocket)
 t_send = threading.Thread(target=send_to_server, args=(clientSocket,))
 # call the function to receive message server
 #recv_from_server(clientSocket)
 t_rcv = threading.Thread(target=recv_from_server, args=(clientSocket,))
 threads.append(t_send)
 threads.append(t_rcv)
 t_send.start()
 t_rcv.start()
 t_send.join()
 t_rcv.join()
 print('EXITING')
 sys.exit()
# This is where the program starts
if __name__ == '__main__':
 main()
answered Feb 8, 2019 at 19:51
Sign up to request clarification or add additional context in comments.

Comments

0

Your first problem is likely due to the fact that python sockets are blocking by default. What this means is that, for example, on the line message = s.recv(1024), your program will keep listening and won't move on to the rest of your script until it receives something.

If you want two people to be able to receive and send at the same time, you might want to look into non-blocking sockets and some asynchronous programming. This how-to from the official documentation might help you: https://docs.python.org/2/howto/sockets.html#non-blocking-sockets

answered Feb 8, 2019 at 19:34

4 Comments

Ok I will look into the docuement and try to understand it
I have read it but I don't know where to include the solution in my code
@system123456 if you are just looking for get the solution and include it somewhere in your code, it would be difficult. Please try to understand the flow. How the code is working.
@yaken Ok I will try but have you found a solution for my second problem?
0

System123456 the problem is that you built a client-server system when the server listens and the client connects to it. Try looking at peer-to-peer systems instead where each node is an equal. For building a chat room you might review DHT nodes.

answered Feb 8, 2019 at 19:39

2 Comments

do you know a solution to my second problem?
Yes, but it doesn't solve your overall problem. The comment about the non-blocking sockets can help your server handle mutliple clients. But the real problem isn't your code, it's your architecture. If you want to build a chat system your clients need to talk to each other. With the client-server architecture your clients only talk to the server. That's why I suggested peer-to-peer. Python is easy to build a DHT peer-to-peer system that does just what you want.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.