Форум по операционной системе GNU/Linux и свободному программному обеспечению
Текущее время: 19 мар 2019, 04:36

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
 Заголовок сообщения: Python: клиент-сервер
Непрочитанное сообщениеДобавлено: 22 фев 2019, 18:54 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11633
Откуда: Харьков
Понадобилось написать сильно специализированный клиент-сервер, для создания сервиса на облаке для распознавания лиц людей (вопрос: зачем? - заказчик попросил и платит ;-) ).
Поскольку это распознавание лиц, то это должен быть Python ... + разнообразные средства-утилиты Linux, такие как NetCat, inetd/xinetd и т.п.
Там есть насколько разнообразных составляющих проблем в составе общей проблемы...


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
 Заголовок сообщения: Re: Python: клиент-сервер
Непрочитанное сообщениеДобавлено: 22 фев 2019, 19:03 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11633
Откуда: Харьков
Olej писал(а):
Понадобилось написать сильно специализированный клиент-сервер,

Базовый клиент-сервер:
- клиент отправляет поток, полученный из SYSIN ...
- сервер возвращает длину полученного потока (позже это будет изображение);

- echo_srv.py :
Код:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import argparse
import socketserver
from tcpip import *

parser = argparse.ArgumentParser() 
parser.add_argument( '-p', '--port', type=int, default = PORTt, help = 'TCP/IP port' )
parser.add_argument( '-v', '--verbose', action = 'count', help = 'increase output verbosity' )
args = vars( parser.parse_args() )

debug_level = 0                                          # verbose level
if args[ 'verbose' ] != None:
    debug_level = int( args[ 'verbose' ] )
if debug_level:
    print( 'version {}'.format( version ) )   
if debug_level > 1:
    print( 'options: {}'.format( args ) )

class MyTCPHandler( socketserver.BaseRequestHandler ):
    def handle( self ):
        self.data = b''
        while True:
            s = self.request.recv( bufsize )
            self.data += s
            if( len( s ) < bufsize ): break
        if debug_level:
            print("{} wrote {} bytes".format( self.client_address[ 0 ], len( self.data ) ) )
        self.request.sendall( bytes( str( len( self.data ) ) + '\n', 'utf-8' ) )

# Create the server, binding to INADDR_ANY on port
with socketserver.TCPServer( ( '', PORTt ), MyTCPHandler ) as server:
    # Activate the server; this will keep running until you interrupt the program with Ctrl-C
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()
        print()


- echo_cli.py :
Код:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import argparse
import socket
import sys
from tcpip import *

parser = argparse.ArgumentParser() 
parser.add_argument( '-p', '--port', type=int, default = PORTt, help = 'TCP/IP port' )
parser.add_argument( '-a', '--address', default = HOST, help = 'server IP address' )
parser.add_argument( '-v', '--verbose', action = 'count', help = 'increase output verbosity' )
args = vars( parser.parse_args() )

debug_level = 0                                # verbose level
if args[ 'verbose' ] != None:
    debug_level = int( args[ 'verbose' ] )
if debug_level:
    print( 'version {}'.format( version ) )
if debug_level > 1:
    print( 'options: {}'.format( args ) )

data = b''
while( True ):       
    s = sys.stdin.read( bufsize )              # read from SYSIN
    s = bytes( s, 'utf-8' )
    if b'' == s: break                         # EOF
    data += s
if debug_level > 1: print( 'input data length {}'.formar( len( data ) ) )

# Create a socket (SOCK_STREAM means a TCP socket)
with socket.socket( socket.AF_INET, socket.SOCK_STREAM ) as sock:
    # Connect to server and reply with data
    sock.connect( ( args[ 'address' ], args[ 'port' ] ) )
    sock.sendall( data )
    # Receive data from the server and shut down
    received = b''
    while True:
        s = sock.recv( bufsize )
        received += s
        if( len( s ) != bufsize ): break
    sock.close()

if debug_level:
    print( "Sent:     {}...".format( data[ : 50 ] ) )
    print( "Received: {}...".format( received[ : 50 ] ) )
print( "Reply:    {}".format( str( received, 'utf-8' ).strip() ) )


Вложения:
echo_srv.py [1.36 КБ]
Скачиваний: 2
echo_cli.py [1.58 КБ]
Скачиваний: 2
tcpip.py [82 байт]
Скачиваний: 2
Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
 Заголовок сообщения: Re: Python: клиент-сервер
Непрочитанное сообщениеДобавлено: 22 фев 2019, 19:06 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11633
Откуда: Харьков
Olej писал(а):
Базовый клиент-сервер:

Выглядит это так:
Код:
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud$ ./echo_srv.py -v
version 0.22
127.0.0.1 wrote 44 bytes
127.0.0.1 wrote 44 bytes
127.0.0.1 wrote 44 bytes
127.0.0.1 wrote 10 bytes
^C

Код:
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud$ ./echo_cli.py -a localhost < 44.txt -v
version 0.22
Sent:     b'1111111111111111111111111111111111111111111\n'...
Received: b'44\n'...
Reply:    44
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud$ ./echo_cli.py -a 127.0.0.1 < 44.txt
Reply:    44
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud$ ./echo_cli.py -a localhost < 44.txt -v
version 0.22
Sent:     b'1111111111111111111111111111111111111111111\n'...
Received: b'44\n'...
Reply:    44
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud$ ./echo_cli.py -a localhost -v
version 0.22
1234
5678
Sent:     b'1234\n5678\n'...
Received: b'10\n'...
Reply:    10


Вложения:
44.txt [44 байт]
Скачиваний: 2
Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
 Заголовок сообщения: Re: Python: клиент-сервер
Непрочитанное сообщениеДобавлено: 22 фев 2019, 19:43 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11633
Откуда: Харьков
Olej писал(а):
Там есть насколько разнообразных составляющих проблем в составе общей проблемы...

Ещё задача из того же комплекса:
- забрасывать на сервере файлы-изображения в заданный каталог...
- с сохранением имён исходных файлов, которыми наполняется каталог.
Не хотелось для этого делать специальное приложение - обойдёмся утилитами Linux... (nc, tar, gzip)

- передаём файлы по сети скриптом known_cli_add:
Код:
#!/bin/bash

if [ $# -eq 0 ]
then
   echo "using: $1 <file1 file2 ...>"
   exit 1
fi

PORTk=54321

for f
do
   tar -czf- "$f" | nc 87.249.221.249 $PORTk
   echo "$f file sent"
done

exit 0

- на приёмном, серверном хосте работает принимающий скрипт:
Код:
#!/bin/bash

if [ $# -eq 0 ]
then
   echo "using: $1 <known faces directory>"
   exit 1
fi

cd $1
if [ $? != 0 ]
then
   exit 2
fi

PORTk=54321

while [ 0 ]
do
   nc -l -p $PORTk | tar -xzf- 2>/dev/null
   if [ $? != 0 ]
   then
      rm -f * 2>/dev/null
   fi
done

Запускаем на сервере 87.249.221.249:
Код:
android@android-vm:~/FaceDL/cloud$ ./known_srv_add known2
...

Код:
android@android-vm:~/FaceDL/cloud$ tree known2
known2

0 directories, 0 files

Пересылаем файлы с клиента:
Код:
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud$ ./known_cli_add Egor1.2.jpg Olena3.4.jpg
Egor1.2.jpg file sent
Olena3.4.jpg file sent

Они появляются на сервере в нужном каталоге:
Код:
android@android-vm:~/FaceDL/cloud$ tree known2
known2
├── Egor1.2.jpg
└── Olena3.4.jpg

0 directories, 2 files

android@android-vm:~/FaceDL/cloud$ ls -l known2
total 44
-rw-rw-r-- 1 android android 23454 Жел 12 18:06 Egor1.2.jpg
-rw-rw-r-- 1 android android 20381 Жел 12 18:20 Olena3.4.jpg

Таким образом можем добавлять сколько угодно в каталог эталонов...
Для очистки каталога (тем же серверным скриптом) имеем другого клиента known_cli_clean:
Код:
#!/bin/bash

if [ $# -ne 0 ]
then
   echo "using: $0"
   exit 1
fi

PORTk=54321

echo "" | nc 87.249.221.249 $PORTk
if [ $? == 0 ]
then
   echo "all filed deleted"
fi
exit 0

Выполняю очистку:
Код:
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud$ ./known_cli_clean
all filed deleted

На сервере:
Код:
android@android-vm:~/FaceDL/cloud$ tree known2
known2

0 directories, 0 files


Вложения:
known_srv_add.sh [315 байт]
Скачиваний: 2
known_cli_add.sh [251 байт]
Скачиваний: 2
known_cli_clean.sh [250 байт]
Скачиваний: 2
Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
 Заголовок сообщения: Re: Python: клиент-сервер
Непрочитанное сообщениеДобавлено: 01 мар 2019, 17:24 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11633
Откуда: Харьков
Olej писал(а):
Базовый клиент-сервер:
- клиент отправляет поток, полученный из SYSIN ...
- сервер возвращает длину полученного потока (позже это будет изображение);

Тут я немного намудрил в коде - требует переделки:
- при чтении в сервере из TCP сокета с длиной 1024 ( s = self.request.recv( bufsize ) ) принятый объём данных в реальной сети (не localhost) может быть любым - от 1 до 1024 байт, поэтому признаком конца передачи может быть только чтение 0 байт:
Код:
        while True:
            s = self.request.recv( bufsize )
            if( 0 == len( s ) ): break
            self.data += s

- для того отличить конец передачи, чтобы сервер смог получить свой 0, клиент должен после передачи полузакрыть сокет:
Код:
with socket.socket( socket.AF_INET, socket.SOCK_STREAM ) as sock:
    # Connect to server and reply with data
    sock.connect( ( args[ 'address' ], args[ 'port' ] ) )
    sock.sendall( data )
...

- и, наконец, чтобы серверу можно было передать данные не только с терминала, но и бинарные данные большого объёма, по каналу перенаправления, входное чтение клиента переделаем так:
Код:
data = b''
while True:       
    s = sys.stdin.buffer.read( bufsize )              # read from SYSIN
    if 0 == len( s ): break                           # EOF
    data += s
...


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
 Заголовок сообщения: Re: Python: клиент-сервер
Непрочитанное сообщениеДобавлено: 01 мар 2019, 17:38 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11633
Откуда: Харьков
Olej писал(а):
Тут я немного намудрил в коде - требует переделки:

Передача:
Код:
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud$ ls -l Egor1.2.ppm
-rw-r--r-- 1 olej olej 921660 фев 22 22:49 Egor1.2.ppm

olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud$ ./echo_cli.py -vv < Egor1.2.ppm
version 0.28
options: {'address': '87.249.221.249', 'port': 30000, 'verbose': 2}
input data length 921660
Sent:     b'P6\n# Created by GIMP version 2.10.8 PNM plug-in\n64'...
Received: b'921660\n'...
Reply:    921660

И на приёме смотрим последовательность длин принимаемых участков данных:
Код:
android@android-vm:~/FaceDL/cloud$ ./echo_srv.py -vvv
version 0.28
options: {'verbose': 3, 'port': 30000}
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
1024
1024
248
1024
1024
848
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
1024
1024
1024
248
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
1024
848
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
1024
848
1024
1024
1024
1024
248
1024
424
1024
1024
848
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
1024
848
1024
1024
848
1024
1024
848
1024
1024
848
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
1024
1024
1024
1024
672
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
992
1024
1024
1024
1024
1024
672
1024
424
1024
424
1024
1024
848
1024
1024
1024
1024
1024
672
1024
1024
848
1024
1024
1024
1024
248
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
1024
1024
248
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
1024
848
1024
1024
1024
1024
248
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
1024
1024
1024
672
1024
424
1024
424
1024
1024
848
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
1024
1024
1024
248
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
1024
848
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
1024
424
732
0
193.28.177.125 wrote 921660 bytes
...

При этом передающий клиент находится под Тель-Авивом, а принимающий сервер - в Челябинске.


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
 Заголовок сообщения: Re: Python: клиент-сервер
Непрочитанное сообщениеДобавлено: 01 мар 2019, 17:50 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11633
Откуда: Харьков
Olej писал(а):
И на приёме смотрим последовательность длин принимаемых участков данных:

Обращаем внимание на "гуляние" длин принимаемых фрагментов данных (ни о каких "пакетах" в TCP говорить бессмысленно!). У TCP сокета есть множество настроечных данных: алгоритм Нэйгла, отсроченные подтверждения, ширина окна приёма и др., при вариациях которых принимаемые длины будут гулять как-угодно и по-другому.

P.S. В TCP потоке нет никаких делений на пакеты, сообщения. Поэтому разделять сообщения в TCP потоке можно (существуют практики):
- для текстовой передачи данных - 2 последовательных '\n' подряд (пустая строка); так работают HTTP (GET и POST), SIP и мн. другие протоколы прикладного уровня;
- передавать длину последующего бинарного сообщения перед самим сообщением;
- полузакрывать (по записи) сокет после передачи сообщения;
- посылать уведомление о завершении сообщения по приоритетному каналу TCP (ургентные сообщения);
Это то, что я знаю, встречал, вспоминаю по памяти...


Вложения:
echo_cli.py [1.65 КБ]
Скачиваний: 2
echo_srv.py [1.39 КБ]
Скачиваний: 2
Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB
[ Time : 0.203s | 18 Queries | GZIP : On ]