#sockets #python-3.x #tcp
#сокеты #python-3.x #tcp
Вопрос:
Клиент отправляет имя файла на сервер. Сервер сканирует файловую систему для всех экземпляров файла и заполняет словарь ключами в качестве абсолютных путей и значениями в качестве размеров файлов.
Написанный мной код кажется логически правильным, но иногда выполняется успешно, а иногда выдает ошибку.
Сервер
import socket;
import sys;
import os;
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
host = socket.gethostname();
port = 49000;
serverSocket.bind((host, port));
serverSocket.listen(1);
while True:
connectionSocket, address = serverSocket.accept();
fileName = connectionSocket.recv(1024).decode();
dictionary = {};
for path, dirs, files in os.walk(os.path.abspath(os.sep)):
for f in files:
if f == fileName:
dictionary[os.path.join(path, f)] = os.stat(f).st_size / 1024;
if len(dictionary) == 0:
connectionSocket.send(('0').encode());
print();
print('File not found!');
sys.exit();
else:
connectionSocket.send(('1').encode());
connectionSocket.send(str(len(dictionary)).encode());
for key, value in dictionary.items():
connectionSocket.send(key.encode('utf-16'));
# If i don't write following line, error vanishes
connectionSocket.send(str(value).encode('utf-16'));
# File transfer
f = open(fileName, 'rb');
byte = f.read(1024);
while (byte):
#print('Sending...');
connectionSocket.send(byte);
byte = f.read(1024);
f.close();
print();
print('Done sending.');
connectionSocket.close();
break;
Клиент
import socket;
import sys;
import os;
if len(sys.argv) != 2:
print();
print('Invalid arguments!');
sys.exit();
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
host = socket.gethostname();
port = 49000;
clientSocket.connect((host, port));
clientSocket.send((sys.argv[1]).encode());
if clientSocket.recv(1024).decode() == '0':
print();
print('File not found!');
sys.exit();
dictionary_size = int(clientSocket.recv(1024).decode());
for i in range(dictionary_size):
print();
print(clientSocket.recv(1024).decode('utf-16'));
# If I don't write this line, error vanishes
print(float(clientSocket.recv(1024).decode('utf-16')));
# File Transfer
byte = clientSocket.recv(1024);
f = open('Received_' sys.argv[1], 'wb');
while (byte):
#print ('Receiving...');
f.write(byte);
byte = clientSocket.recv(1024);
f.close();
print();
print('Done receiving.');
clientSocket.shutdown(socket.SHUT_WR);
clientSocket.close();
Комментарии:
1. TCP — это поток. Первый вызов recv может использовать или не использовать полные данные, отправленные другой стороной. Решение, вероятно, будет включать что-то вроде значения start, stop и seperator между фактическими значениями. Затем ваш принимающий код может восстанавливаться до получения конечного символа
2. Когда это не работает, в чем ошибка? Пожалуйста, предоставьте полную обратную трассировку, если это возможно. Пара комментариев: 1) Python не является C / C , поэтому вам не нужно завершать каждое утверждение с помощью a
;
. 2) Вы не отправляете размер файла, выражениеos.stat(f).st_size / 1024
вычисляет только целое количество блоков 1K, но усечение из-за целочисленного деления не учитывает какой-либо конечный частичный блок.3. Какую ошибку вы видите?
4. Ошибка: i.imgur.com/fW1FscL.png
5. @martineau Вы сказали, что os.stat(f).st_size / 1024 дает целое число, но когда я его печатаю (), оно дает правильный размер с плавающим значением. Недавно я начал использовать Python. ‘;’ — старая привычка. Это плохая практика?