N
N
Nahs2015-12-03 21:14:42
Python
Nahs, 2015-12-03 21:14:42

How to organize parallel work on a network with several devices?

There are approximately 100 devices. By functionality - a pager (received data, displayed). Everyone communicates over the network with the server on the same IP and port.
The server catches the connection. Generates an individual line for each. And sends to the device. A minute later, a new line is formed and sent to the device in the same way.
A couple of questions arose during the process.
1. With the help of which it will be better to organize the work of the server. I shoveled a bunch of articles on various modules and frameworks, but did not figure out which is better to use.
2. To begin with, I tried to implement using threads, but the question arose with the completion of the thread.
The bottom line is that the device periodically goes into reconnect. As a result, a non-closed socket remains on the server and an active thread that has become unnecessary. I can't figure out how to trace the disconnect and close the socket with the stream.

#!/usr/bin/env python
# -*- coding: utf-8 -*-



"""
An echo server that uses threads to handle multiple clients at a time.
Entering any line of input at the terminal will exit the server.
"""

import select, socket, sys, threading,  datetime, random, time
from tablo import Tablo

class Server:
    def __init__(self):
        self.host = ''
        self.port = 33335
        self.backlog = 5
        self.size = 1024
        self.server = None
        self.threads = []

    def open_socket(self):
        try:
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server.bind((self.host,self.port))
            self.server.listen(self.backlog)
            print(u'Слушаем: %s' % self.port)
        except socket.error as e:
            if self.server:
                self.server.close()
            print ("Could not open socket: %s" % e.message)
            sys.exit(1)

    def run(self):
        self.open_socket()
        running = 1
        while running:
            #cli, addr = self.server.accept()
            inputready,_,_ = select.select([self.server],[],[])
            #inputready, _, _ = select.select([addr, ], [], [])

            for s in inputready:
                if s == self.server:
                    # handle the server socket
                    cli, addr = self.server.accept()
                    c = Client(cli, addr)
                    c.start()
                    self.threads.append(c)

                elif s == sys.stdin:
                    # handle standard input
                    sys.stdin.readline()
                    running = 0 
                    print('running', running)

        # close all threads

        self.server.close()
        print('Server Close')
        for c in self.threads:
            c.join()

class Client(threading.Thread):
    def __init__(self, client, address):
        threading.Thread.__init__(self)
        self.client = client
        self.address = address
        self.size = 1024
        print(u'Поймали', address)
        print(u'Активных потоков', threading.active_count())

    def run(self):
        running = 1
        while running:
            data = self.client.recv(self.size)
            if data:
                if data[:3] == b'REG':
                    IMEI = str(data[3:18], 'ascii');
                    print(IMEI)
                    if IMEI[:10] == 'Call Ready':
                        print(IMEI[:10])
                        break
                    #print(u'Получено: %s : %s' % (self.addr, data))
                    pack = Tablo.setDynamicString(1, 'KZN', 'Happy first Winter Day', random.randint(5,20))
                    #pack = Tablo.setTemperature('+93')
                    #pack = Tablo.setTime()
                    self.client.send(pack)
                    print(u'Отправлена строка %s %s' % (threading.currentThread().name, IMEI), datetime.datetime.now())
                        
                elif data[0] == 89:
                    print(u'Команда принята %s %s' % (threading.currentThread().name, IMEI), datetime.datetime.now())
                    time.sleep(60)
                    pack = Tablo.setDynamicString(1, 'KZN', 'Dooms Day is coming', random.randint(5,20))
                    self.client.send(pack)
                    #print(u'Отправлено %s %s: %s' % (threading.currentThread().name, IMEI, pack))
                    print(u'Отправлена строка %s %s' % (threading.currentThread().name, IMEI), datetime.datetime.now())
                elif data == b'SetTemp':
                    print(u'Установлена температура',datetime.datetime.now())
                elif data == b'TDSet':
                    print(u'Установлено время',datetime.datetime.now())
                else:
                    print(u'Неизвестный ответ', data)
            else:
                self.client.close()
                print('Socket Close')
                running = 0

if __name__ == "__main__":
    s = Server()
    s.run()

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
nirvimel, 2015-12-03
@Nahs

  1. It is better to write such servers not on threads threading(which still rest against the GIL), but on "green" threads, for example gevent , which is designed to solve problems like yours with maximum performance.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question