1

I have been trying for so long to create a chat between 2 clients. I also need to check if 1 client is disconnecting so the server will be shut down.

I have no idea why it isn't working, can someone help me?

This is my code:

from threading import Thread
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(("localhost", 1234))
s.listen(5)
def handleclient(sender,reciever):
    while True:
        data = sender.recv(1024)
        if data == "":
             close()
        else:
            reciever.send(data)
def close():
    s.shutdown(socket.SHUT_RDWR)
    s.close()
    print ("closed")
while True:
    (client_s, client_addr) = s.accept()
    (client_s1, client_addr1) = s.accept()
    t = Thread(target=handleclient, args=(client_s,client_s1))
    t1 = Thread(target=handleclient, args=(client_s1,client_s))
    t.start()
    t1.start()
Neucro
  • 252
  • 2
  • 6
  • 1
    Does [When does socket.recv(recv_size) return?](https://stackoverflow.com/questions/7174927/when-does-socket-recvrecv-size-return) answer your question? you aren't sending anything to `sender` but it is the first statement in the while loop. – wwii Dec 15 '20 at 14:41
  • 1
    Did you read the [Socket Programming HOWTO](https://docs.python.org/3/howto/sockets.html#using-a-socket) in the Python documentation? – wwii Dec 15 '20 at 15:24

1 Answers1

2

It does not work because you have written code before knowing what you wanted it to do... A bit nitpicking, but you really you first describe in english (or whatever your first language is) what is expected to happen.

Apart from that, there is a true mistake in if data == "": recv returns a byte string, so it should at least be if data == b"":.

Another problem lies at s.shutdown(socket.SHUT_RDWR). s is not in connected state (like sender or reciever are) but in listening state. It does not make sense to shutdown it and it should raise an error.

But cleanly closing the server is not that easy. The main thread is waiting on accept on s. If you close it from another thread you will get an exception, so you have to protect it in a try block.

And you should decide what should happen for the main thread when a conversation between 2 clients ends. Currently you are trying to stop the server, but then the while True loop around the accept calls does not really make sense. Without knowing that I cannot propose you a fixed code...

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Doesn't `sender.recv(1024)` block if nothing is being sent? ... Stopping the while loop in its tracls? – wwii Dec 15 '20 at 14:46
  • @wwii: it does but in the child threads. It is indeed possible to implement a [graceful shutdown](https://stackoverflow.com/a/27777498/3545273) in the child threads, but that does not say what to do in the main one with the listening socket. – Serge Ballesta Dec 15 '20 at 14:50
  • I'll have to remember that phrase. – wwii Dec 15 '20 at 15:01