mr.pihto
			  Авг. 29, 2010 12:41:22
		 	 
			
				я написал многопоточный сервер способный принимать сообщения от разных клиентов и отправлять их тем же самым клиентам.. но вот как сделать так чтобы сообщение приходя с одного клиента уходило на другой клиент?
клиент
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()
 
		
			
			  Lexander
			  Авг. 29, 2010 13:37:06
		 	 
			
				Это зависит от того сколько клиентов со сколькими клиентами должны обмениваться информацией.
Если 1 с 1, то можете взять за пример код чата из соседней ветки, если N с M (N, M > 1) то вам нужно организовать промежуточное хранилище на сервере для сообщений и сведений о последнем полученном сообщении для каждого клиента. Это может быть БД, например. В том числе, хранящаяся только в памяти.
			
		 
		
			
			  Ed
			  Авг. 29, 2010 13:48:55
		 	 
			
				Вот чисто для примера, ваш сервер, рассылающий сообщения всем подключеным клиентам:
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()
 
		
			
			  Lexander
			  Авг. 29, 2010 13:58:34
		 	 
			
				Но он имеет ограничения. Например, на длину сообщения, время и надежность доставки.
			
		 
		
			
			  Ed
			  Авг. 29, 2010 14:55:08
		 	 
			
				Кстати, я заметил, что народ предпочитает ковыряться с socket вместо пользования SocketServer. Это просто от того, что люди не знают о существовании второго или знают и предпочитают делать все с нуля?
			
		 
		
			
			  mr.pihto
			  Авг. 29, 2010 15:35:25
		 	 
			
				Ed, можете прокомментировать пожалуйста этот код?
			
		 
		
			
			  Ed
			  Авг. 29, 2010 16:23:28
		 	 
			
				А что именно непонятно? Когда клиент заходит на сервер, то сервер добавляет его адрес и сокет в словарик, который виден во всх тредах. Этот словарик используется, когда сервер получает сообщение от клиента. Он пробегает по словарику и рассылает сообщение всем остальным клиентам.
Это просто пример. В реальной жизни нужно как минимум следить за тем, чтобы из словаря удалялись клиенты, которые отвалились(закрыли соединение) и отправлять сообщения не всем клиентам, а только тем, которым оно предназначено. Второе возможно только зная специфику приложения, то есть соответствие login-а клиента его адресу/сокету.