我正在嘗試從 FTP 服務器列印檔案目錄。我有兩個套接字:第一個向服務器發送命令,第二個用于獲取請求的資料。要決議資料,我想LIST多次發送命令,但我不知道如何正確執行此操作。這是我的代碼:
import socket
HOST = '[IP address]'
USERNAME = '[login]'
PASSWORD = '[password]'
sock_1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_1.connect((HOST, 21))
sock_1.recv(1024)
sock_1.send(f'USER {USERNAME}\r\n'.encode())
sock_1.recv(1024)
sock_1.send(f'PASS {PASSWORD}\r\n'.encode())
sock_1.recv(1024)
sock_1.send('PASV\r\n'.encode())
response_values = sock_1.recv(1024).decode('utf-8').split(',')
port_high = int(response_values[-2])
port_low = int(response_values[-1].replace(').\r\n', ''))
port = port_high*256 port_low
sock_2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_2.connect((HOST, port))
# Works as expected.
sock_1.send('LIST\r\n'.encode())
print(sock_1.recv(4096))
print(sock_2.recv(4096))
# Here comes a problem.
sock_1.send('LIST\r\n'.encode())
print(sock_1.recv(4096))
print(sock_2.recv(4096))
我得到的輸出:
b'150 Here comes the directory listing.\r\n'
b'[a totally expected array of bytes that fits into the buffer entirely]'
b'226 Directory send OK.\r\n'
b''
我覺得我在理論上做錯了什么,但由于我是套接字編程的新手,我無法弄清楚到底是什么。
我想我每次想發送另一個命令時都可以重新創建連接,但必須有更好的解決方案。
uj5u.com熱心網友回復:
我想我每次想發送另一個命令時都可以重新創建連接,但必須有更好的解決方案。
FTP 有一個用于所有命令的控制連接和一個用于傳輸資料的每個命令的資料連接。因此控制連接(sock_1在您的代碼中)將保持打開狀態,但必須為每個新的 LIST 命令建立新的資料連接。
創建一個新的資料連接意味著發送 PASV 命令,決議回應以獲取新的服務器端地址并連接到該地址,然后(在 LIST 的情況下)從該資料連接讀取所有資料,直到另一端關閉連接(recv回傳0)。
這些實際上都不是特定于套接字編程的,而是在應用程式層定義 FTP 協議的方式 - 有關詳細資訊,請參閱RFC 959。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/532381.html
上一篇:vue點擊按列清空值排序
