vaukalak
Март 3, 2011 01:10:56
В общем написал сервак:
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
users_ids=[]
clients = []
def handle(self):
user_id=self.request.recv(1024).strip()
already_logged_in = False
for i in range(len(self.users_ids)):
if(self.users_ids[i] == user_id):
already_logged_in = True
break
if not already_logged_in:
print "client: %s connected as " % self.client_address[0] + user_id
self.users_ids.append(user_id)
self.clients.append(self.request)
response = "connected"
else:
response = "already logged in"
self.request.send(response)
for i in range(len(self.clients)):
if(self.clients[i] != self.request):
self.clients[i].send("new user connected")
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
И клиент:
import socket
import sys
import time
HOST, PORT = "localhost", 9999
data = " ".join(sys.argv[1:])
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
sock.send(data)
while 1:
time.sleep(0.03)
received = sock.recv(1024)
if(received != ""):
print "Received: %s" % received
Идея такая. Запуская из коммандного промта клиент, я передаю ему ID по которому он логиниться. Сервак сохраняет его в списке. Каждый раз как кто ни будь логиниться, всем рассылается сообщение “new user connected”. И вот в этом месте вываливается:
Exception happened during processing of request from ('127.0.0.1', 2851)
Traceback (most recent call last):
File “C:\Python27\lib\SocketServer.py”, line 284, in _handle_request_noblock
self.process_request(request, client_address)
File “C:\Python27\lib\SocketServer.py”, line 310, in process_request
self.finish_request(request, client_address)
File “C:\Python27\lib\SocketServer.py”, line 323, in finish_request
self.RequestHandlerClass(request, client_address, self)
File “C:\Python27\lib\SocketServer.py”, line 639, in __init__
self.handle()
File “C:\Python27\tcp server\server.py”, line 24, in handle
self.clients.send(“new user connected”)
File “C:\Python27\lib\socket.py”, line 170, in _dummy
raise error(EBADF, ‘Bad file descriptor’)
error: Bad file descriptor
—————————————-
Андрей Светлов
Март 3, 2011 01:33:58
Догадайтесь с трех раз: что происходит с сервером, когда клиент закрывается?
vaukalak
Март 3, 2011 01:47:57
while 1:
time.sleep(0.03)
received = sock.recv(1024)
if(received != ""):
print "Received: %s" % received
Ну я этот код и написал что бы клиент не закрывался. Приложение работает, метод close я не вызывал. По этому не могу понять почему сокет закрывается. (я на питоне начал писать вчера).
o7412369815963
Март 3, 2011 21:35:37
вместо этого:
already_logged_in = False
for i in range(len(self.users_ids)):
if(self.users_ids[i] == user_id):
already_logged_in = True
break
можно написать:
already_logged_in = user_id in self.users_ids
c SocketServer.BaseRequestHandler не работал, но теократический после завершения метода handle, сервер (до)отправляет данные и закрывает соединение с клиентом.
vaukalak
Март 4, 2011 11:04:49
o7412369815963, спасибо за подсказку.
Но может мне все же скажет кто ни будь, как же оставить соединение открытым?
Андрей Светлов
Март 4, 2011 12:41:43
Предположение неверное, сервер сокет сам не закрывает.
Еще раз:
запустили сервер
запустили клиент
закрыли клиент
запустили клиент - и все поломалось.
Почему?
vaukalak
Март 4, 2011 15:12:10
Андрей Светлов, а где клиент, в моем коде, закрывается?
Я вижу картину так:
запустили сервер
запустили клиент
запустили второй клиент
сервер пытается уведомить об этом первого - и все поломалось.
Вот я и не понимаю почему(
Андрей Светлов
Март 4, 2011 16:06:16
Был неправ. Верно, после выхода из Request.handle() сокет прикрывается. Извиняюсь.
vaukalak
Март 4, 2011 17:01:57
Тогда понятно. А есть ли способ его как то переоткрыть? Ведь как по другому я отправлю клиенту сообщение?
Андрей Светлов
Март 4, 2011 17:18:24
Если оставаться в рамках SocketServer - то не нужно выходить из Request.handle
И чем скорее вы изобретете тот или иной (предпочтительно пакетный) протокол общения - тем вам будет легче.