Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 29, 2010 12:41:22

mr.pihto
От:
Зарегистрирован: 2010-08-29
Сообщения: 21
Репутация: +  0  -
Профиль   Отправить e-mail  

Сокеты. обмен данными междудвумя клиентами

я написал многопоточный сервер способный принимать сообщения от разных клиентов и отправлять их тем же самым клиентам.. но вот как сделать так чтобы сообщение приходя с одного клиента уходило на другой клиент?

клиент

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("127.0.0.1", 7500))
while 1:
buf = raw_input('->Server ')
sock.send(buf)
result = sock.recv(1024)
print "Server: ", result
sock.close()
сервер
import socket, threading
class MyThread(threading.Thread):
def __init__(self, sock, addr):
self.sock = sock
self.addr = addr
threading.Thread.__init__(self)
def run (self):
while 1:
try:
buf = self.sock.recv(1024)
print "Client:", buf
self.sock.send(buf)
except:
print 'Connection reset by peer'
break
self.sock.close()
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.bind(("", 7500))
srv.listen(5)
while 1:
sock, addr = srv.accept()
MyThread(sock,addr).start()



Офлайн

#2 Авг. 29, 2010 13:37:06

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Сокеты. обмен данными междудвумя клиентами

Это зависит от того сколько клиентов со сколькими клиентами должны обмениваться информацией.
Если 1 с 1, то можете взять за пример код чата из соседней ветки, если N с M (N, M > 1) то вам нужно организовать промежуточное хранилище на сервере для сообщений и сведений о последнем полученном сообщении для каждого клиента. Это может быть БД, например. В том числе, хранящаяся только в памяти.



Офлайн

#3 Авг. 29, 2010 13:48:55

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Сокеты. обмен данными междудвумя клиентами

Вот чисто для примера, ваш сервер, рассылающий сообщения всем подключеным клиентам:

import socket, threading

sockets = {}

class MyThread(threading.Thread):
def __init__(self, sock, addr):
self.sock = sock
self.addr = addr
threading.Thread.__init__(self)
def run (self):
while 1:
try:
buf = self.sock.recv(1024)
print "Got %s from %s(%s)" % (buf, self.addr, self.sock)
for addr, sock in sockets.iteritems():
if addr != self.addr and sock != self.sock:
print "Sending %s to %s(%s)" % (buf, addr, sock)
sock.send(buf)
except:
print 'Connection reset by peer'
break
self.sock.close()
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.bind(("", 7500))
srv.listen(5)
while 1:
sock, addr = srv.accept()
sockets[addr] = sock
MyThread(sock,addr).start()



Отредактировано (Авг. 29, 2010 13:49:47)

Офлайн

#4 Авг. 29, 2010 13:58:34

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Сокеты. обмен данными междудвумя клиентами

Но он имеет ограничения. Например, на длину сообщения, время и надежность доставки.



Офлайн

#5 Авг. 29, 2010 14:55:08

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Сокеты. обмен данными междудвумя клиентами

Кстати, я заметил, что народ предпочитает ковыряться с socket вместо пользования SocketServer. Это просто от того, что люди не знают о существовании второго или знают и предпочитают делать все с нуля?



Офлайн

#6 Авг. 29, 2010 15:35:25

mr.pihto
От:
Зарегистрирован: 2010-08-29
Сообщения: 21
Репутация: +  0  -
Профиль   Отправить e-mail  

Сокеты. обмен данными междудвумя клиентами

Ed, можете прокомментировать пожалуйста этот код?



Офлайн

#7 Авг. 29, 2010 16:23:28

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Сокеты. обмен данными междудвумя клиентами

А что именно непонятно? Когда клиент заходит на сервер, то сервер добавляет его адрес и сокет в словарик, который виден во всх тредах. Этот словарик используется, когда сервер получает сообщение от клиента. Он пробегает по словарику и рассылает сообщение всем остальным клиентам.
Это просто пример. В реальной жизни нужно как минимум следить за тем, чтобы из словаря удалялись клиенты, которые отвалились(закрыли соединение) и отправлять сообщения не всем клиентам, а только тем, которым оно предназначено. Второе возможно только зная специфику приложения, то есть соответствие login-а клиента его адресу/сокету.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version