簡體   English   中英

如何發送/接收多個數據? 蟒蛇套接字?

[英]how to send/receive multiple data? python socket?

我正在嘗試發送/接收多個數據。 服務器完美發送文件名和文件數據。 問題出在客戶端。 我創建了一個名為 filename 和 filedata 的兩個變量。 filename 變量接收帶有文件數據的文件名。 filedata 什么也沒收到,因為 filename 收到了所有的文件名和文件數據。 我不知道為什么文件名收到文件名+數據? 我該如何解決這個問題?

這是我的代碼:

服務器.py

import socket

def send():
    host = 'localhost'
    port = 9999
    address = (host, port)

    sock = socket.socket()
    sock.bind(address)
    sock.listen(5)
    print('listining for connection...')

    con,addr = sock.accept()
    print('Got connection from',addr)

    file1name = 'file1.txt'
    con.send(file1name.encode('utf-8'))
    file1data = 'this is file 1'
    con.send(file1data.encode('utf-8'))

    file2name = 'file2.txt'
    con.send(file2name.encode('utf-8'))
    file2data = 'this is file 2'
    con.send(file2data.encode('utf-8'))

    con.close()
    sock.shutdown(1)
    sock.close()
    print('connection closed!')

send()

客戶端.py

import socket

host = 'localhost'
port = 9999
address = (host, port)

sock = socket.socket()
sock.connect(address)
print('connected to', address)

while True:
    filename = sock.recv(60).decode('utf-8')
    if not filename:
        break
    print('filename -', filename)
    data = sock.recv(60).decode('utf-8')
    print('data -', data)


sock.shutdown(1)
sock.close()

輸出服務器.py

listining for connection...
Got connection from ('127.0.0.1', 36886)
connection closed!

輸出客戶端.py

connected to ('localhost', 9999)
filename - file1.txtthis is file 1file2.txtthis is file 2
data - 

主要問題是您必須在開始接收之前將數據大小發送到客戶端。

我假設服務器發送一個 unsigned int 32bit(4byte) 來表示大小。

參見 client.py 中的 soc.recv(4)

服務器.py

from socket import *
import os
import ctypes

HOST = 'localhost'
PORT = 9999
ADDRESS = (HOST, PORT)
BUF_SIZE = 1024
PATH = './uploads'

soc = socket(AF_INET, SOCK_STREAM)
soc.bind(ADDRESS)
soc.listen(5)
print('listen for connection...')
con,addr = soc.accept()
print('got connection from', addr)
print('-------------------------')

def sendFile(socket, path):
    filename = os.path.basename(path)

    filename_bytes = filename.encode('utf-8')
    filename_size = ctypes.c_uint32(len(filename_bytes))
    file_size = ctypes.c_uint32(os.stat(path).st_size)

    socket.send(bytes(filename_size)) # send uint32 (4 bytes)
    socket.send(filename_bytes)
    socket.send(bytes(file_size)) # send uint32 (4 bytes)

    with open(path, 'rb') as f:
        filecontent = f.read(BUF_SIZE)
        while filecontent:
            socket.send(filecontent)
            filecontent = f.read(BUF_SIZE)

files = os.listdir(PATH)
num_files = ctypes.c_uint32(len(files))
con.send(bytes(num_files))
for file in files:
    sendFile(con, os.path.join(PATH, file))

客戶端.py

from socket import *
import os
import ctypes

HOST = 'localhost'
PORT = 9999
ADDRESS = (HOST, PORT)
BUF_SIZE = 1024
PATH = './downloads'

soc = socket(AF_INET, SOCK_STREAM)
soc.connect(ADDRESS)
print('connected to', ADDRESS)

def recvFile(socket):
    tmp = soc.recv(4)
    filename_size = int.from_bytes(tmp, byteorder='little')
    print('filename_size =', filename_size)
    filename = soc.recv(filename_size).decode('utf-8')
    print('filename =', filename)
    tmp = soc.recv(4)
    file_size = int.from_bytes(tmp, byteorder='little')
    print('file_size =', file_size)

    with open(os.path.join(PATH, filename), 'wb') as f:
        while file_size > 0:
            filecontent = soc.recv(min(BUF_SIZE, file_size))
            f.write(filecontent)
            file_size -= len(filecontent)
    print('data recvd')

tmp = soc.recv(4)
num_files = int.from_bytes(tmp, byteorder='little')

for i in range(num_files):
    print('{}/{}'.format(i+1, num_files))
    recvFile(soc)

soc.shutdown(SHUT_RDWR)
soc.close()
print('socket closed')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM