I'm running windows 10, python 2.7 using pycharm I'm doing as an exercise a socket chat room, and I've stumbled on a certain problem:
While running the client and server socket from multiple cmd windows, When I exit one cmd window abruptly, the server is supposed to forward a message to the remaining client - informing them that a client left (including the client's nick)
For some reason it proves to be a problem, the server seems to retain that client in the client list, raising an error as if I sent him that message (which obviously is problematic, because he is no longer there).
When I tried to fix that - changing the loop to not send the message to that specific client (by saving his socket object) -it doesn't send any message. As if it doesn't recognize the other clients.
My code:
Server:
import socket
import select
import datetime
server_socket=socket.socket()
server_socket.bind(('127.0.0.1',23))
server_socket.listen(5)
open_client_sockets = []
messages_to_send = []
chat_clients={}
def send_waiting_messages(wlist):
for message in messages_to_send:
(sender,msg)=message
if(msg=='\r'):
continue
elif(msg=='quit'):
pass
else:
nick_len=int(msg[:2])
nick=msg[2:2+nick_len]
chat=msg[2+nick_len:]
chat_clients[sender]=nick
for client in wlist:
if(msg=='quit'):
client.send(('{:02d}:{:02d} {} has left the chat!'.format(datetime.datetime.now().hour,datetime.datetime.now().minute,sender)))
else:
if(client is sender):
client.send('NL')
else:
client.send('{:02d}:{:02d} {}: {}'.format(datetime.datetime.now().hour,datetime.datetime.now().minute,nick,chat))
messages_to_send.remove(message)
while True:
rlist,wlist,xlist=select.select([server_socket] + open_client_sockets,open_client_sockets,[])
for current_socket in rlist:
print wlist
if(current_socket is server_socket):
(new_socket,address)=server_socket.accept()
open_client_sockets.append(new_socket)
chat_clients[new_socket]=''
else:
try:
msg=current_socket.recv(1024)
except socket.error as e:
if e.errno==10054:
msg=''
else:
raise
if(msg=='' or msg=='quit'):
if(msg=='quit'):
messages_to_send.append((chat_clients[current_socket], 'quit'))
current_socket.send('quit')
open_client_sockets.remove(current_socket)
del chat_clients[current_socket]
else:
print '{:02d}:{:02d} {} has left the chat!'.format(datetime.datetime.now().hour,
datetime.datetime.now().minute, chat_clients[current_socket])
messages_to_send.append((current_socket, 'quit'))
else:
print msg
messages_to_send.append((current_socket,msg))
send_waiting_messages(wlist)
Client:
import socket
import select
import datetime
server_socket=socket.socket()
server_socket.bind(('127.0.0.1',23))
server_socket.listen(5)
open_client_sockets = []
messages_to_send = []
chat_clients={}
def send_waiting_messages(wlist):
for message in messages_to_send:
(sender,msg)=message
if(msg=='\r'):
continue
elif(msg=='quit'):
pass
else:
nick_len=int(msg[:2])
nick=msg[2:2+nick_len]
chat=msg[2+nick_len:]
chat_clients[sender]=nick
for client in wlist:
if(msg=='quit'):
client.send(('{:02d}:{:02d} {} has left the chat!'.format(datetime.datetime.now().hour,datetime.datetime.now().minute,sender)))
else:
if(client is sender):
client.send('NL')
else:
client.send('{:02d}:{:02d} {}: {}'.format(datetime.datetime.now().hour,datetime.datetime.now().minute,nick,chat))
messages_to_send.remove(message)
while True:
rlist,wlist,xlist=select.select([server_socket] + open_client_sockets,open_client_sockets,[])
for current_socket in rlist:
print wlist
if(current_socket is server_socket):
(new_socket,address)=server_socket.accept()
open_client_sockets.append(new_socket)
chat_clients[new_socket]=''
else:
try:
msg=current_socket.recv(1024)
except socket.error as e:
if e.errno==10054:
msg=''
else:
raise
if(msg=='' or msg=='quit'):
if(msg=='quit'):
messages_to_send.append((chat_clients[current_socket], 'quit'))
current_socket.send('quit')
open_client_sockets.remove(current_socket)
del chat_clients[current_socket]
else:
print '{:02d}:{:02d} {} has left the chat!'.format(datetime.datetime.now().hour,
datetime.datetime.now().minute, chat_clients[current_socket])
messages_to_send.append((current_socket, 'quit'))
else:
print msg
messages_to_send.append((current_socket,msg))
send_waiting_messages(wlist)
Help would be much appreciated!
I have also been trying trying to make a chat room and I have been successful. You might want to look at my code to find the solution.
Server
import threading
from queue import Queue
import socket
host = ''
port = 5000
client_list = []
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1000)
def conn():
while True:
(host, port) = s.accept()
f = len(client_list)
client_list.append(host)
print(client_list)
p1 = threading.Thread(target=clientam, args=str(f))
p2 = threading.Thread(target=threader)
p2.start()
p1.start()
p1.join()
p2.join()
def clientam(client):
size = 3000
client = int(client)
c = client_list[client]
print(c)
c.send("Welcome to the chatroom".encode())
while True:
try:
data = c.recv(size).decode()
if data == "exit":
for l in client_list:
if l == c:
pass
else:
l.send("The other person has left the chatroom".encode())
client_list[client] = ''
print(client_list)
c.close()
break
else:
for l in client_list:
if l == c:
pass
else:
l.send(data.encode())
except Exception:
for l in client_list:
if l == c:
continue
else:
try:
l.send("The other person has left the chatroom".encode())
except Exception:
pass
break
try:
c.close()
except Exception:
break
def threader():
t = threading.Thread(target=conn)
t.start()
t.join()
threader()
client
import socket
import threading
import time
import pickle
host = '127.0.0.1'
port = 5000
s = socket.socket()
d = 0
print_lock = threading.Lock()
def conn():
global d
global s
try:
if d == 1:
s = socket.socket()
s.connect((host, port))
d = 0
elif d == 0:
s.connect((host, port))
except Exception:
conn()
def reciever():
global d
global g
g = False
li = [128, 3, 88, 0, 113, 46]
size = 3000
while True:
try:
data = s.recv(size).decode()
data = str(data)
with open('Data.txt', 'a') as f:
f.write(data)
if str(data) == 'The other person has left the chatroom':
with print_lock:
print(data)
elif str(data) == "Welcome to the chatroom":
g = True
with print_lock:
print(str(data))
else:
try:
int(data)
continue
except Exception:
with print_lock:
print("Other Person:> " + str(data))
except Exception as e:
with print_lock:
print("You have been disconnected")
d = 1
s.close()
with print_lock:
print('Trying to connect to server')
conn()
def sender():
global d
global g
while True:
if g == True:
while True:
with print_lock:
i = input('You:> ')
if i == 'exit':
try:
s.send(i.encode())
with print_lock:
print("You have been disconnected")
d = 1
except Exception:
with print_lock:
print('You have been disconnected')
d = 1
elif i == "connect":
if d == 0:
with print_lock:
print("Server already connected")
elif d == 1:
with print_lock:
print('Server connecting')
conn()
else:
try:
if d == 0:
s.send(i.encode())
elif d == 1:
with print_lock:
print('Server is disconnected')
except Exception:
with print_lock:
print('Server is disconnected')
def threader():
p1 = threading.Thread(target = reciever)
p1.start()
p2 = threading.Thread(target = sender)
p2.start()
p1.join()
p2.join()
conn()
threader()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.