jbardin / scp.py

scp module for paramiko
Other
538 stars 137 forks source link

SCP continuous file transmission error channel is closed. #197

Closed 654sd closed 3 hours ago

654sd commented 4 days ago

My operating system is: MacOS & Windows 10. My Python environment is: Python 3.8 (I have also tried Python 3.12 and 3.11) My environment: I am mapping a hardware device similar to a Raspberry Pi onto my computer by mapping the operating system directory on the hardware device, and then connecting to it via SSH to modify files or perform maintenance. The problem I am facing: The put function of the SCP module is failing repeatedly with an error message of "Channel closed" when uploading files multiple times.

Here are some problems I have found:

Execute the code:

import paramiko import scp client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) The client connects to the hostname '127.0.0.1'. port=22, username='root', password='alpine') p_scp = scp.SCPClient(transport=client.get_transport(), socket_timeout=15.0) p_scp.put('test', recursive=False, remote_path='/var/testfile') print('The transfer was successful') p_scp.close() client.close()

Execution Results:

The transfer was successful

! image

The SCP module will not produce an error and run normally when it performs the put function only once.

But when I use SCP to continuously upload files, it gives me an error.

Run the code

import paramiko import scp client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) The client connects to the hostname '127.0.0.1'. port=22, username='root', password='alpine') p_scp = scp.SCPClient(transport=client.get_transport(), socket_timeout=15.0) p_scp.put('test', recursive=False, remote_path='/var/testfile') p_scp.put('test7', recursive=False, remote_path='/var/testfile7') print('The transfer was successful') p_scp.close() client.close()

Execution Results:

Traceback (most recent call last): File "/Users/macos/PyCode/pythonProject/GithubBug/SCPBug/test.py", line 11, in p_scp.put('test7', recursive=False, remote_path='/var/testfile7') The file "/Users/macos/PyBin/T2/lib/python3.8/site-packages/scp.py" is line 198, and the function being called is "put". self.channel.exec_command(scp_command + The file "/Users/macos/PyBin/T2/lib/python3.8/site-packages/paramiko/channel.py" contains line 70, where the function "_check" is defined. return func(self, *args, **kwds) The file "/Users/macos/PyBin/T2/lib/python3.8/site-packages/paramiko/channel.py" line 255 is:

def exec_command(self, command):

This is a method in the paramiko.transport.Transport class, which is used to execute a command on the remote server. self._wait_for_event() 文件路径为 "/Users/macos/PyBin/T2/lib/python3.8/site-packages/paramiko/channel.py" 的第 1224 行:

self._wait_for_event(timeout) raise e paramiko.ssh_exception.SSHException: Channel closed.

! image

It can be seen that only the test file was uploaded successfully, but an error occurred when uploading the test7 file, with the message "Channel closed." (I have already ruled out issues with permissions, files, and memory usage. Permissions are in place, the file is not the problem, and the file is only 7kb in size.)

After that, I started trying to solve the problem:

Execute the code:

import paramiko import scp import time client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) The client connects to the hostname '127.0.0.1'. port=22, username='root', password='alpine') p_scp = scp.SCPClient(transport=client.get_transport(), socket_timeout=15.0) p_scp.put('test', recursive=False, remote_path='/var/testfile') time.sleep(10) p_scp.put('test7', recursive=False, remote_path='/var/testfile7') print('The transfer was successful') p_scp.close() client.close()

Execution Results:

The transfer was successful

! image

This code successfully outputs "The transfer was successful," but the test7 file was not successfully transferred.

remram44 commented 4 days ago

Again, please use proper markdown formatting, this is very difficult to read. If this issue even different from #196?

654sd commented 4 days ago

同样,请使用正确的 markdown 格式,这很难阅读。如果这个问题甚至与 #196 不同?

SCP_Module_Error_Analysis.pdf This is my corrected pdf, please preview it

remram44 commented 4 days ago

I can't accept bug reports in PDF. Please use markdown.

654sd commented 4 days ago

SCP Module Error: "Channel Closed"

Operating System and Environment

Problem Description

The put function of the SCP module fails with the error "Channel closed" when attempting multiple file uploads in succession. A single file upload works correctly.

Test Code and Results

Single File Upload (Success)


import paramiko
import scp

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

client.connect(hostname='127.0.0.1', port=22, username='root', password='alpine')
p_scp = scp.SCPClient(transport=client.get_transport(), socket_timeout=15.0)
p_scp.put('test', recursive=False, remote_path='/var/testfile')
print('The transfer was successful')
p_scp.close()
client.close()
Execution Result:

arduino
复制代码
The transfer was successful
The file test is successfully uploaded.

Multiple File Upload (Failure)
python
复制代码
import paramiko
import scp

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

client.connect(hostname='127.0.0.1', port=22, username='root', password='alpine')
p_scp = scp.SCPClient(transport=client.get_transport(), socket_timeout=15.0)
p_scp.put('test', recursive=False, remote_path='/var/testfile')
p_scp.put('test7', recursive=False, remote_path='/var/testfile7')
print('The transfer was successful')
p_scp.close()
client.close()
Execution Result:

arduino
复制代码
Traceback (most recent call last):
  File "/Users/macos/PyCode/pythonProject/GithubBug/SCPBug/test.py", line 11, in
  p_scp.put('test7', recursive=False, remote_path='/var/testfile7')

  File "/Users/macos/PyBin/T2/lib/python3.8/site-packages/scp.py", line 198, in put
    self.channel.exec_command(scp_command +

  File "/Users/macos/PyBin/T2/lib/python3.8/site-packages/paramiko/channel.py", line 70, in _check
    return func(self, *args, **kwds)

paramiko.ssh_exception.SSHException: Channel closed.
Only the test file is uploaded successfully. Uploading test7 fails with the error "Channel closed".

Debugging Attempt
Added a delay between the two uploads using time.sleep():

python
复制代码
import paramiko
import scp
import time

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

client.connect(hostname='127.0.0.1', port=22, username='root', password='alpine')
p_scp = scp.SCPClient(transport=client.get_transport(), socket_timeout=15.0)
p_scp.put('test', recursive=False, remote_path='/var/testfile')
time.sleep(10)
p_scp.put('test7', recursive=False, remote_path='/var/testfile7')
print('The transfer was successful')
p_scp.close()
client.close()
Execution Result:

arduino
复制代码
The transfer was successful
However, the file test7 was not successfully uploaded, despite no error being thrown.

Conclusion
The error "Channel closed" occurs when attempting to upload multiple files in succession using the SCPClient from the scp Python module. Introducing a delay between uploads allows the second file upload to proceed without an error, but the second file is still not successfully uploaded. This issue may require further investigation into connection handling or transport management.
remram44 commented 3 hours ago

Duplicate of #196