2 개의 파일 [ "img1.jpg", "img2.jpg"]을 포함하는 내 문서 폴더의 내용을 보내려고하는 간단한 클라이언트-서버 프로그램이 있습니다.
작동:
서버는 클라이언트가 연결될 때까지 기다렸다가 메시지를 수신하지만 메시지가 text : files이면 생성 할 새 폴더의 이름과 시작할 파일의 양을 수신하는 createExp () 함수가 있습니다. 받다.
이 데이터로 사용자가 서버에 지시 한 파일 수에 따라 반복해야하는 for주기를 시작합니다.
주기 :
이주기는 클라이언트가 보낸 각 파일의 데이터를 수신 한 후 지정된 경로에 저장하는 기능을 가지고 있습니다.
발행물:
서버는 데이터의 작은 부분을 올바르게 수신했지만 오류가 발생합니다.
Traceback (most recent call last):
File "C:\Users\Dell\Desktop\servidor_recv_archivo.py", line 53, in <module>
if msgp.decode() == "files":
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 5: invalid
start byte
server.py
import socket
import os
def bytes_to_int(b):
result = 0
for i in range(4):
result += b[i]<<(i*8)
return result
def makeExp(client):
while True:
FolderName = client.recv(1024).decode()
NumberFiles = client.recv(1024).decode()
print(FolderName,NumberFiles)
if not os.path.exists(FolderName):
os.mkdir(FolderName)
for element in range(int(NumberFiles)):
size = client.recv(4)
size = bytes_to_int(size)
current_size = 0
buffer = b""
while current_size < size:
data = client.recv(1024)
if not data:
break
if len(data) + current_size > size:
data = data[:size-current_size]
buffer += data
current_size += len(data)
with open(str(element),"wb") as f:
f.write(buffer)
break
ip = "192.168.8.8"
port = 5555
data = (ip,port)
listen = 2
server = socket.socket()
server.bind(data)
server.listen(listen)
client,direction = server.accept()
while True:
try:
msgp = client.recv(1024)
print(msgp)
client.sendall("Msg recv".encode())
if msgp.decode() == "files":
makeExp(client)
except ConnectionResetError:
print("{} ".format(direction))
break
client.py
import socket
import os
def convert_to_bytes(length):
result = bytearray()
result.append(length&255)
for i in range(3):
length = length>>8
result.append(length&255)
return result
def makeFolder(client):
rute = "C:/Users/AngelHp/Desktop/Documentos"
FolderName = os.path.basename("C:/Users/AngelHp/Desktop/Documentos")
NumberFiles = str(len(os.listdir("C:/Users/AngelHp/Desktop/Documentos")))
client.sendall(FolderName.encode())
client.sendall(NumberFiles.encode())
for element in (os.listdir(rute)):
length = os.path.getsize(rute+"/"+element)
client.send(convert_to_bytes(length))
with open(rute+"/"+element,"rb") as infile:
d = infile.read(1024)
while d:
client.send(d)
d = infile.read(1024)
ip = "192.168.8.8"
port = 5555
client = socket.socket()
client.connect((ip,port))
while True:
msg = input("> ")
if msg != "files": #Al oprimir el boton guarar en serv, lanzara la funcion crearExpServ
client.sendall(msg.encode())
reply = client.recv(1024).decode()
print(reply)
elif msg == "files":
print("ok")
makeFolder(client)
@mark-수정 됨
import socket
with socket.socket() as s:
s.bind(('',8000))
s.listen(1)
with s.accept()[0] as c:
chunks = []
while True:
chunk = c.recv(4096)
if not chunk: break
chunks.append(chunk)
for i in range(2):
with open('image{}.png'.format(str(i)),'wb') as f:
f.write(b''.join(chunks))
cieent.py
import socket
import os
with socket.socket() as s:
s.connect(('localhost',8000))
for elemento in os.listdir("img"):
print(elemento)
with open("img"+"/"+elemento,'rb') as f:
s.sendall(f.read())
TCP는 메시지 경계 개념이없는 스트리밍 프로토콜이므로 인쇄 msgp
하면 예상보다 더 많이 수신 된 것을 볼 수 있습니다 (예 : 폴더 이름, 파일 수 및 바이너리 파일 데이터의 일부). 해당 데이터는 UTF-8로 인코딩되지 않았기 때문에 UnicodeDecodeError가 발생합니다.
프로토콜을 정의하고 프로토콜을 만족할 때까지 소켓에서 데이터를 버퍼링해야합니다 (예 : 개행 문자로 읽기). 또한 소켓을 파일 류 객체로 감싸는 socket.makefile 도 참조하십시오 . 메소드는 유사 .readline()
하고 .read(n)
존재하므로 다음과 같은 프로토콜을 정의 할 수 있습니다.
위의 프로토콜을 구현하는 예 (클라이언트가 프로토콜을 위반하는 경우 오류 처리 없음) 보낼 폴더를 한두 개 준비한 다음 다른 터미널에서 서버를 시작하고 다운로드 폴더 client.py <folder>
로 전송 <folder>
합니다.
# server.py
import socket
import traceback
import os
s = socket.socket()
s.bind(('',8000))
s.listen(1)
while True:
client,address = s.accept()
print(f'{address} connected')
# client socket and makefile wrapper will be closed when with exits.
with client,client.makefile('rb') as clientfile:
while True:
folder = clientfile.readline()
if not folder: # When client closes connection folder == b''
break
folder = folder.strip().decode()
no_files = int(clientfile.readline())
print(f'Receiving folder: {folder} ({no_files} files)')
folderpath = os.path.join('Downloads',folder) # put in different directory in case server/client on same system
os.makedirs(folderpath,exist_ok=True)
for i in range(no_files):
filename = clientfile.readline().strip().decode()
filesize = int(clientfile.readline())
data = clientfile.read(filesize)
print(f'Receiving file: {filename} ({filesize} bytes)')
with open(os.path.join(folderpath,filename),'wb') as f:
f.write(data)
# client.py
import socket
import sys
import os
def send_string(sock,string):
sock.sendall(string.encode() + b'\n')
def send_int(sock,integer):
sock.sendall(str(integer).encode() + b'\n')
def transmit(sock,folder):
print(f'Sending folder: {folder}')
send_string(sock,folder)
files = os.listdir(folder)
send_int(sock,len(files))
for file in files:
path = os.path.join(folder,file)
filesize = os.path.getsize(path)
print(f'Sending file: {file} ({filesize} bytes)')
send_string(sock,file)
send_int(sock,filesize)
with open(path,'rb') as f:
sock.sendall(f.read())
s = socket.socket()
s.connect(('localhost',8000))
with s:
transmit(s,sys.argv[1])
두 개의 폴더를 준비하고 "client Folder1"과 "client Folder2"를 실행했습니다. 클라이언트 터미널 출력 :
C:\test>client Folder1
Sending folder: Folder1
Sending file: file1 (13 bytes)
Sending file: file2 (13 bytes)
Sending file: file3 (13 bytes)
Sending file: file4 (13 bytes)
C:\test>client Folder2
Sending folder: Folder2
Sending file: file5 (13 bytes)
Sending file: file6 (13 bytes)
출력 (server.py) :
C:\test>server
('127.0.0.1', 2303) connected
Receiving folder: Folder1 (4 files)
Receiving file: file1 (13 bytes)
Receiving file: file2 (13 bytes)
Receiving file: file3 (13 bytes)
Receiving file: file4 (13 bytes)
('127.0.0.1', 2413) connected
Receiving folder: Folder2 (2 files)
Receiving file: file5 (13 bytes)
Receiving file: file6 (13 bytes)
기타 예 :
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다