Python的ftplib破坏了发送的文件 - Winsock问题?

时间:2017-07-07 22:10:33

标签: python winsock2 ftplib

我们有一个Python应用程序,用于在我们的PC和IBM i中型系统上的SVN检出之间来回传输源文件。

它已经使用多年而没有任何问题。

最近,当我们从PC发送到IBM i时,我们已经开始看到源文件被破坏了。目的地的线路无序。 Wireshark表示数据无法正常运行。

有时它工作正常,有时它会出现一两行乱序,有时会出现很多行。

在出现此问题之前,脚本没有更改。

这是Python代码中的storlines()调用:

connection.storlines('STOR ' + ibmi_file, open(source_file.fullpath, 'rb'))

最初,我在Windows 10上使用Python 2.7.12。我尝试升级到2.7.13,但我仍然看到了问题。我尝试转到3.6.1,但我仍然看到了这个问题。

其他开发人员也看到了这个问题,运行各种版本的Python和Windows。

我下载了3.6.1源代码,并在socketmodule.c中的sock_sendall()和sock_send_impl()中添加了一些调试日志记录。

我可以看到从sock_send_impl()发送以下内容。

来源
line# - length(bytes)
1 - 79
2 - 73
3 - 38
4 - 73
5 - 78
6 - 41

Wireshark显示以下FTP数据包。

数据包# - FTP数据长度
1 - 79
2 - 1452

问题是数据包2从源代码行开始:

2,5,3,4

据我了解,sock_send_impl()是将数据传递给操作系统的地方。我意识到Nagle's algorithm用于将小发送组合成一个更大的TCP数据包。

但该数据包中的数据应与传递给send的顺序相同。它不是。

我认为它可能与最近的一些Windows补丁有关,除了我们的一位使用Mac的开发人员看到相同的(?)问题。

我们确实有一位运行Windows 7的开发人员至少报告过他没有看过这个问题(他已经离开了)。

这对我没有任何意义,我不知道从哪里开始。

1 个答案:

答案 0 :(得分:1)

我们有理由相信这个问题是由赛门铁克Vontu版本14.6 MP1引起的;这是一种数据丢失防护(DLP)产品,可以在数据包离开PC之前对其进行“检查”。

我相信这个问题已报告给赛门铁克。

与此同时,我们通过扩展基础ftplib.FTP类并添加新功能来解决此问题:

#stortext combines block read from STORBINARY with ASCII transfer mode from STORLINE
def stortext(self, cmd, fp, blocksize=8192, callback=None, rest=None):
    self.voidcmd('TYPE A')
    conn = self.transfercmd(cmd, rest)
    while 1:
        buf = fp.read(blocksize)
        if not buf: break
        conn.sendall(buf)
        if callback: callback(buf)
    conn.close()
    return self.voidresp()

我们不再遇到乱码问题。作为奖励,转移运行速度比storline快得多。

所以我们继续使用我们的新功能。