2013-07-03 2 views
16

Я создал простой многопоточный tcp-сервер, используя модуль pingon threding. Этот сервер создает новый поток каждый раз, когда подключается новый клиент.Многопоточный TCP-сервер в Python

#!/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() 

Затем я открыл два новых терминала и подключился к серверу с помощью netcat. Затем, когда я печатаю и отправляю свои первые данные на сервер, используя первый подключенный терминал, ответ от сервера приходит на другой терминал и первое соединение отключается. Я угадал причину, но я сомневаюсь, что это происходит, потому что переменная clientock переписывается так, что она относится к сокету второго соединения. Правильно ли я, а затем, как этого избежать?

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

+3

Не беспокойтесь, это хороший вопрос. Добро пожаловать в StackOverflow! – Jordan

+0

Кажется, что вы никогда не доходите до последних двух строк. Это намеренно? –

ответ

13

Вы должны передать клиента носок нить, как вы делаете с IP- адреса и порта:

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) 
... 
+1

спасибо !! Он работал красиво. Благодарю. :) – Deepal

+0

Я использую python 2.7. Я внес рекомендуемые изменения, но после подключения второго клиента netcat первый клиент зависает. Я не совсем понимаю, что происходит. У кого-нибудь еще есть эта проблема? – John

0

Я создал этот хороший класс, который вы можете переопределить

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 

И вот пример:

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() 

 Смежные вопросы

  • Нет связанных вопросов^_^