Python: клиент-сервер
Модератор: Olej
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Python: клиент-сервер
Понадобилось написать сильно специализированный клиент-сервер, для создания сервиса на облаке для распознавания лиц людей (вопрос: зачем? - заказчик попросил и платит ).
Поскольку это распознавание лиц, то это должен быть Python ... + разнообразные средства-утилиты Linux, такие как NetCat, inetd/xinetd и т.п.
Там есть насколько разнообразных составляющих проблем в составе общей проблемы...
Поскольку это распознавание лиц, то это должен быть Python ... + разнообразные средства-утилиты Linux, такие как NetCat, inetd/xinetd и т.п.
Там есть насколько разнообразных составляющих проблем в составе общей проблемы...
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python: клиент-сервер
Базовый клиент-сервер: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()
Код: Выделить всё
#!/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 КБ) 105 скачиваний
-
- echo_cli.py
- (1.58 КБ) 98 скачиваний
-
- tcpip.py
- (82 байт) 100 скачиваний
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python: клиент-сервер
Выглядит это так: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 байт) 102 скачивания
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python: клиент-сервер
Ещё задача из того же комплекса: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
Код: Выделить всё
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 байт) 97 скачиваний
-
- known_cli_add.sh
- (251 байт) 106 скачиваний
-
- known_cli_clean.sh
- (250 байт) 101 скачивание
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python: клиент-сервер
Тут я немного намудрил в коде - требует переделки: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
Код: Выделить всё
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
...
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python: клиент-сервер
Передача: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
...
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python: клиент-сервер
Обращаем внимание на "гуляние" длин принимаемых фрагментов данных (ни о каких "пакетах" в TCP говорить бессмысленно!). У TCP сокета есть множество настроечных данных: алгоритм Нэйгла, отсроченные подтверждения, ширина окна приёма и др., при вариациях которых принимаемые длины будут гулять как-угодно и по-другому.Olej писал(а): И на приёме смотрим последовательность длин принимаемых участков данных:
P.S. В TCP потоке нет никаких делений на пакеты, сообщения. Поэтому разделять сообщения в TCP потоке можно (существуют практики):
- для текстовой передачи данных - 2 последовательных '\n' подряд (пустая строка); так работают HTTP (GET и POST), SIP и мн. другие протоколы прикладного уровня;
- передавать длину последующего бинарного сообщения перед самим сообщением;
- полузакрывать (по записи) сокет после передачи сообщения;
- посылать уведомление о завершении сообщения по приоритетному каналу TCP (ургентные сообщения);
Это то, что я знаю, встречал, вспоминаю по памяти...
- Вложения
-
- echo_cli.py
- (1.65 КБ) 101 скачивание
-
- echo_srv.py
- (1.39 КБ) 101 скачивание
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 7 гостей