TCP 소켓을 통해 여러 파일 보내기

Revsky01

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)존재하므로 다음과 같은 프로토콜을 정의 할 수 있습니다.

  1. 폴더 이름 + 줄 바꿈 보내기
  2. 파일 수 + 개행 보내기
  3. 파일 이름 # 1 + 개행 보내기
  4. 파일 크기 + 줄 바꿈 보내기
  5. 정확히 "파일 크기"바이트의 이진 데이터를 보냅니다.
  6. 나머지 파일에 대해 3-5를 반복합니다.

위의 프로토콜을 구현하는 예 (클라이언트가 프로토콜을 위반하는 경우 오류 처리 없음) 보낼 폴더를 한두 개 준비한 다음 다른 터미널에서 서버를 시작하고 다운로드 폴더 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] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

파이썬에서 TCP 소켓을 통해 파일 보내기

TCP / IP 소켓 (웹 서버)을 통해 파일 보내기

TCP 소켓을 통해 파일 보내기 C++ | 창

Java 소켓을 통해 여러 파일 보내기

C의 소켓을 사용하여 TCP를 통해 오디오 파일 보내기

TCP 소켓 파이썬을 통해 단일 바이트 보내기

파이썬에서 TCP 소켓을 통해 클라이언트-서버 간 파일 보내기?

VB.Net을 사용하여 TCP를 통해 파일을 보내고 Python3.6에서 소켓으로 수신하는 동안 파일 인코딩 오류

C에서 tcp 소켓을 통해 HTTP를 통해 파일을 어떻게 보내나요?

TCP를 사용하여 소켓을 통해 파일을 전송할 때 멈춤

파이썬 3에서 소켓을 통해 파일 보내기

소켓을 통해 파일 보내기-버퍼 크기

TCP 소켓을 통해 큰 Base64 문자열 보내기

c의 tcp 소켓을 통해 구조체 보내기

불완전한 TCP 소켓을 통해 char 버퍼 보내기

TCP 소켓을 통해 16진수 변수 보내기

Python에서 TCP 소켓을 통해 목록 보내기

소켓을 통해 여러 데이터 보내기

소켓 연결을 통해 여러 요청 보내기

struct.pack을 사용하여 파일의 전체 크기를 가져오고 TCP 소켓을 통해 서버로 보냅니다.

C ++를 사용하여 TCP를 통해 파일 보내기, 잘못된 크기로 축소

소켓을 통해 큰 파일 보내기

소켓을 통해 PC에서 Android로 파일 보내기

소켓을 통해 대용량 JSON 파일 보내기

소켓을 통해 Jar 파일 보내기

c에서 소켓을 통해 여러 파일을 보내는 방법은 무엇입니까?

VB.NET에서 소켓을 사용하여 TCP를 통해 바이트 배열 보내기

소켓을 사용하여 여러 파일 Python 보내기

여러 메일을 통해 대용량 메일 첨부 파일 보내기

TOP 리스트

  1. 1

    JNDI를 사용하여 Spring Boot에서 다중 데이터 소스 구성

  2. 2

    std :: regex의 일관성없는 동작

  3. 3

    JSoup javax.net.ssl.SSLHandshakeException : <url>과 일치하는 주체 대체 DNS 이름이 없습니다.

  4. 4

    PrematureCloseException : 연결이 너무 일찍 닫혔습니다.

  5. 5

    Xcode10 유효성 검사 : 이미지에 투명성이 없지만 여전히 수락되지 않습니까?

  6. 6

    정점 셰이더에서 카메라에서 개체까지의 XY 거리

  7. 7

    Ionic 2 로더가 적시에 표시되지 않음

  8. 8

    Seaborn에서 축 제목 숨기기

  9. 9

    C #에서 'System.DBNull'형식의 개체를 'System.String'형식으로 캐스팅 할 수 없습니다.

  10. 10

    복사 / 붙여 넣기 비활성화

  11. 11

    ArrayBufferLike의 typescript 정의의 깊은 의미

  12. 12

    Google Play Console에서 '예기치 않은 오류가 발생했습니다. 나중에 다시 시도해주세요. (7100000)'오류를 수정하는 방법은 무엇입니까?

  13. 13

    Kubernetes Horizontal Pod Autoscaler (HPA) 테스트

  14. 14

    jfreecharts에서 x 및 y 축 선을 조정하는 방법

  15. 15

    PRNG 기간보다 순열이 더 많은 목록을 무작위로 섞는 방법은 무엇입니까?

  16. 16

    C # HttpWebRequest 기본 연결이 닫혔습니다. 전송시 예기치 않은 오류가 발생했습니다.

  17. 17

    다음 컨트롤이 추가되었지만 사용할 수 없습니다.

  18. 18

    잘못된 구성 개체입니다. Webpack이 Angular의 API 스키마와 일치하지 않는 구성 개체를 사용하여 초기화되었습니다.

  19. 19

    Android Kotlin은 다른 활동에서 함수를 호출합니다.

  20. 20

    R의 마침표와 숫자 사이에 문자열 삽입

  21. 21

    Assets의 BitmapFactory.decodeStream이 Android 7에서 null을 반환합니다.

뜨겁다태그

보관