Форум сайта python.su
Всем доброго времени суток!
Решил написать клиент-серверный чат, почитал про сокеты и потоки. Нашел готовый код, который почти удовлетворяет моим требованиям по логике работы.
Сервер:
import socket, threading, string
debug = True
_connector = None
_running = True
_host = '127.0.0.1'
_port = 12345
_maxClient = 999
_recvBuffer = 2000
def printd (aString):
if debug:
print (aString)
class talkToClient (threading.Thread):
def __init__(self, clientSock, addr):
self.clientSock = clientSock
self.addr = addr
threading.Thread.__init__(self)
def run (self):
while True:
recvData = self.clientSock.recv (_recvBuffer)
if not recvData:
self.clientSock.send ('bye')
break
printd('Client ' + str (self.addr) + ' say "' + str (recvData) + '"')
for p in range(len(list)):
self.clientSock.sendto(recvData, list[p])
if recvData == "exit":
break
self.clientSock.close ()
_connector = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
_connector.bind ((str(_host), int(_port)))
_connector.listen (int(_maxClient))
list = []
while _running:
printd ('Running on ' + _host + ':' + str (_port) + '.')
channel, details = _connector.accept ()
list.append(details)
printd ('Conect on : ' + str (details))
talkToClient (channel, details).start ()
_connector.close ()
import socket, string
debug = True
_connector = None
_running = True
_host = '127.0.0.1'
_port = 12345
_recvBuffer = 2000
_connector = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
_connector.connect ((str(_host), int(_port)))
while _running:
sendData = input ("> ")
_connector.send (bytes(sendData,'utf-8'))
recvData = _connector.recv (_recvBuffer)
print (recvData)
if recvData == "bye":
break
if recvData == "exit":
break
_connector.close ()
list.append(details)
for p in range(len(list)):
self.clientSock.sendto(recvData, list[p])
Офлайн
Не знаю как питон отнёсся к переменной с именем “list”, но я-бы ругнулся ))
Одной из причин является возможно блокирующий ввод. Пока пользователь не нажмёт Ентер, то он не увидит входящих сообщений.
Серверная сторона.. бррррр… Я от потоков в питоне отказался, по крайней мере когда в них используются блокирующие функции.
Думаю стоит продумать алгоритм программы заново - и с нуля всё написать. ))
Офлайн
socket.sendto “The socket should not be connected to a remote socket,”
В данном случае сокет в потоке, похоже, подключен, и шлет данные только своему клиенту забив на адрес (если подключить 3 клиента - данные будут отсылаться обратно три раза и так далее)
вот так должно работать:
# -*- coding: utf-8 -*-
import socket, threading, string
debug = True
_connector = None
_running = True
_host = '127.0.0.1'
_port = 12345
_maxClient = 999
_recvBuffer = 2000
def printd (aString):
if debug:
print (aString)
class talkToClient (threading.Thread):
def __init__(self, clientSock, addr):
self.clientSock = clientSock
self.addr = addr
threading.Thread.__init__(self)
def run (self):
while True:
recvData = self.clientSock.recv (_recvBuffer)
if not recvData:
self.clientSock.send ('bye')
break
printd('Client ' + str (self.addr) + ' say "' + str (recvData) + '"')
if recvData == "exit":
break
#-------здесь----------------------->>
for conn in CONNS:
conn.sendData(recvData)
self.clientSock.close ()
def sendData(self, data):
print 'sending to ', self.addr
self.clientSock.send(data)
#----------------------------------
_connector = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
_connector.bind ((str(_host), int(_port)))
_connector.listen (int(_maxClient))
#----и здесь---------------------------
CONNS = []
while _running:
printd ('Running on ' + _host + ':' + str (_port) + '.')
channel, details = _connector.accept ()
printd ('Conect on : ' + str (details))
CONNS.append(talkToClient (channel, details))
print CONNS
CONNS[-1].start ()
_connector.close ()
Отредактировано (Май 6, 2011 13:29:26)
Офлайн