2013-07-03 12 views
16

Python'un ezme modülünü kullanarak basit bir çok dişli tcp sunucusu oluşturdum. Bu sunucu, yeni bir istemci her bağlandığında yeni bir konu oluşturur.Python'da Çok Yönlendirmeli TCP sunucusu

#!/usr/bin/env python 

import socket, threading 

class ClientThread(threading.Thread): 

    def __init__(self,ip,port): 
     threading.Thread.__init__(self) 
     self.ip = ip 
     self.port = port 
     print "[+] New thread started for "+ip+":"+str(port) 


    def run(self):  
     print "Connection from : "+ip+":"+str(port) 

     clientsock.send("\nWelcome to the server\n\n") 

     data = "dummydata" 

     while len(data): 
      data = clientsock.recv(2048) 
      print "Client sent : "+data 
      clientsock.send("You sent me : "+data) 

     print "Client disconnected..." 

host = "0.0.0.0" 
port = 9999 

tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

tcpsock.bind((host,port)) 
threads = [] 


while True: 
    tcpsock.listen(4) 
    print "\nListening for incoming connections..." 
    (clientsock, (ip, port)) = tcpsock.accept() 
    newthread = ClientThread(ip, port) 
    newthread.start() 
    threads.append(newthread) 

for t in threads: 
    t.join() 

Sonra iki yeni terminal açtım ve netcat kullanarak sunucuya bağlandım. Ardından, ilk veriyi bağladığım ilk terminali kullanarak sunucuya ilk veri yazıp gönderdiğimde, sunucudan yanıtı diğer terminale gelir ve ilk bağlantı kesildi. Nedeni tahmin ettim ama bunun gerçekleşip gerçekleşmediğinden şüphe duyuyorum çünkü clientsock değişkeninin üzerine yazıldığından, ikinci bağlantı soketine başvurur. Doğru muyum ve bundan nasıl kurtulurum?

Sınırlı sayıda soket değişkenine sahip bir dizi kullanmak ve her bağlantı için her bir değişkeni kullanmaktan başka bir yolu var mı? Burada bir var bu güzel sınıfı oluşturduk

class ClientThread(threading.Thread): 

    def __init__(self, ip, port, socket): 
     threading.Thread.__init__(self) 
     self.ip = ip 
     self.port = port 
     self.socket = socket 
     print "[+] New thread started for "+ip+":"+str(port) 

    def run(self): 
     # use self.socket to send/receive 

... 
(clientsock, (ip, port)) = tcpsock.accept() 
newthread = ClientThread(ip, port, clientsock) 
... 
+3

Endişelenme, bu iyi bir soru. StackOverflow'a hoş geldiniz! – Jordan

+0

Son iki çizgiye asla ulaşamayacaksınız. Bu kasıtlı mı? –

cevap

13

Sen ip adresi ve port ile yaptıkları gibi iplik istemci çorap geçmelidir örnek:

class BasicChatServer(SocketServer): 

    def __init__(self): 
     SocketServer.__init__(self) 

    def onmessage(self, client, message): 
     print "Client Sent Message" 
     #Sending message to all clients 
     self.broadcast(message) 

    def onopen(self, client): 
     print "Client Connected" 

    def onclose(self, client): 
     print "Client Disconnected" 

def main(): 
    server = BasicChatServer() 
    server.run() 

if __name__ == "__main__": 
    main() 
+1

Teşekkür ederim! Güzel çalıştı. Teşekkürler. :) – Deepal

+0

Python 2.7 kullanıyorum. Önerilen değişiklikleri yaptım, ancak ikinci bir netcat istemcisini bağladıktan sonra, ilk istemci kilitleniyor. Neler olduğunu anlamıyorum. Bu sorunu başka biri var mı? – John

0

Eğer

import socket 
import thread 

class SocketServer(socket.socket): 
    clients = [] 

    def __init__(self): 
     socket.socket.__init__(self) 
     #To silence- address occupied!! 
     self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.bind(('0.0.0.0', 8080)) 
     self.listen(5) 

    def run(self): 
     print "Server started" 
     try: 
      self.accept_clients() 
     except Exception as ex: 
      print ex 
     finally: 
      print "Server closed" 
      for client in self.clients: 
       client.close() 
      self.close() 

    def accept_clients(self): 
     while 1: 
      (clientsocket, address) = self.accept() 
      #Adding client to clients list 
      self.clients.append(clientsocket) 
      #Client Connected 
      self.onopen(clientsocket) 
      #Receiving data from client 
      thread.start_new_thread(self.recieve, (clientsocket,)) 

    def recieve(self, client): 
     while 1: 
      data = client.recv(1024) 
      if data == '': 
       break 
      #Message Received 
      self.onmessage(client, data) 
     #Removing client from clients list 
     self.clients.remove(client) 
     #Client Disconnected 
     self.onclose(client) 
     #Closing connection with client 
     client.close() 
     #Closing thread 
     thread.exit() 
     print self.clients 

    def broadcast(self, message): 
     #Sending message to all clients 
     for client in self.clients: 
      client.send(message) 

    def onopen(self, client): 
     pass 

    def onmessage(self, client, message): 
     pass 

    def onclose(self, client): 
     pass 

geçersiz kılabilir Ve: