簡體   English   中英

通過python中的TCP套接字在客戶端-服務器之間發送文件?

[英]Sending files between client - server through TCP socket in python?

我正在嘗試通過TCP套接字發送和接收文件。 當用戶輸入put abc.txt ,應將abc.txt復制到服務器。
當用戶類型get def.txt ,應將def.txt下載到用戶計算機。 (實際上,我還必須實現2種方法lls列出客戶端目錄中的所有文件, ls列出服務器中的所有文件,但是我還沒有這樣做。)

這是代碼

服務器

import socket
import sys
HOST = 'localhost'                 
PORT = 3820

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind((HOST, PORT))

socket.listen(1)
while (1):
    conn, addr = socket.accept()
    print 'New client connected ..'
    reqCommand = conn.recv(1024)
    print 'Client> %s' %(reqCommand)
    if (reqCommand == 'quit'):
        break
    #elif (reqCommand == lls):
        #list file in server directory
    else:
        string = reqCommand.split(' ', 1)   #in case of 'put' and 'get' method
        reqFile = string[1] 

        if (string[0] == 'put'):
            with open(reqFile, 'wb') as file_to_write:
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    file_to_write.write(data)
                    file_to_write.close()
                    break
            print 'Receive Successful'
        elif (string[0] == 'get'):
            with open(reqFile, 'rb') as file_to_send:
                for data in file_to_send:
                    conn.sendall(data)
            print 'Send Successful'
    conn.close()

socket.close()

客戶

import socket
import sys

HOST = 'localhost'    #server name goes in here
PORT = 3820

def put(commandName):
    socket.send(commandName)
    string = commandName.split(' ', 1)
    inputFile = string[1]
    with open(inputFile, 'rb') as file_to_send:
        for data in file_to_send:
            socket.sendall(data)
    print 'PUT Successful'
    return 

def get(commandName):
    socket.send(commandName)
    string = commandName.split(' ', 1) 
    inputFile = string[1]
    with open(inputFile, 'wb') as file_to_write:
        while True:
            data = socket.recv(1024)
            #print data
            if not data:
                break
            print data
            file_to_write.write(data)
            file_to_write.close()
            break
    print 'GET Successful'
    return

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((HOST,PORT))

msg = raw_input('Enter your name: ')
while(1):
    print 'Instruction'
    print '"put [filename]" to send the file the server '
    print '"get [filename]" to download the file from the server '
    print '"ls" to list all files in this directory'
    print '"lls" to list all files in the server'
    print '"quit" to exit'
    sys.stdout.write ('%s> ' %msg)
    inputCommand = sys.stdin.readline().strip()
    if (inputCommand == 'quit'):
        socket.send('quit')
        break
    # elif (inputCommand == 'ls')
    # elif (inputCommand == 'lls')
    else:
        string = inputCommand.split(' ', 1)
    if (string[0] == 'put'):
        put(inputCommand)
    elif (string[0] == 'get'):
        get(inputCommand)
socket.close()

我無法解決幾個問題。

  1. 該程序僅在第一次時正確運行(“ put”和“ get”方法)。 此后,無法將來自客戶端的所有命令發送到服務器。
  2. “獲取”方法不適用於圖像/照片文件。

發生第一個問題是因為在處理一個命令后,服務器正在關閉連接。

conn.close()

發生第二個問題是因為您沒有從客戶端的套接字讀取所有數據。 在while循環的末尾,您有一個“ break”語句,由於該語句,客戶機在讀取1024個字節后才關閉套接字。 當服務器嘗試在此關閉的套接字上發送數據時,它會在服務器端導致錯誤。

while True:
    data = socket1.recv(1024)
    # print data
    if not data:
        break
    # print data
    file_to_write.write(data)
    file_to_write.close()
    break

有兩種方法可以解決第一個問題。

  1. 更改客戶端,以便為每個命令創建一個新連接並將命令發送到服務器。
  2. 更改服務器以在同一連接上處理多個命令。

以下代碼是更改后的客戶端,以演示解決第一個問題的第一種方法。 它還解決了第二個問題。

import socket
import sys

HOST = 'localhost'    # server name goes in here
PORT = 3820


def put(commandName):
    socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket1.connect((HOST, PORT))
    socket1.send(commandName)
    string = commandName.split(' ', 1)
    inputFile = string[1]
    with open(inputFile, 'rb') as file_to_send:
        for data in file_to_send:
            socket1.sendall(data)
    print 'PUT Successful'
    socket1.close()
    return


def get(commandName):
    socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket1.connect((HOST, PORT))
    socket1.send(commandName)
    string = commandName.split(' ', 1)
    inputFile = string[1]
    with open(inputFile, 'wb') as file_to_write:
        while True:
            data = socket1.recv(1024)
            # print data
            if not data:
                break
            # print data
            file_to_write.write(data)
    file_to_write.close()
    print 'GET Successful'
    socket1.close()
    return


msg = raw_input('Enter your name: ')
while(1):
    print 'Instruction'
    print '"put [filename]" to send the file the server '
    print '"get [filename]" to download the file from the server '
    print '"ls" to list all files in this directory'
    print '"lls" to list all files in the server'
    print '"quit" to exit'
    sys.stdout.write('%s> ' % msg)
    inputCommand = sys.stdin.readline().strip()
    if (inputCommand == 'quit'):
        socket.send('quit')
        break
    # elif (inputCommand == 'ls')
    # elif (inputCommand == 'lls')
    else:
        string = inputCommand.split(' ', 1)
        if (string[0] == 'put'):
            put(inputCommand)
        elif (string[0] == 'get'):
            get(inputCommand)

暫無
暫無

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

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