WebClient抛出SocketException(无效参数)

5
我试图使用下面的代码将文件上传到FTP服务器,但是我收到了一个套接字异常。有人能帮我解决这个异常吗?当我使用UploadFile(uri, filepath)函数时也会遇到相同的问题。
我尝试在WebClient选项中设置凭据为NetworkCredentials,但结果相同。
在远程FTP服务器上也遇到了同样的问题。
我正在使用.NET 4.7.1。
byte[] xmlBytes = XmlDocumentToByteArray(xml);

WebClient webclient = new WebClient() {
    Proxy = null
};

Uri uri = new Uri("ftp://test:test@localhost/test.xml");
//Uri uri = new Uri("ftp://localhost/test.xml");
webclient.UploadData(uri, xmlBytes);

异常: (英文:提供了无效的参数)

System.Net.WebException: Er is een ongeldig argument opgegeven ---> System.Net.Sockets.SocketException: Er is een ongeldig argument opgegeven
   bij System.Net.Sockets.Socket..ctor(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
   bij System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6)
   bij System.Net.PooledStream.Activate(Object owningObject, Boolean async, GeneralAsyncDelegate asyncCallback)
   bij System.Net.PooledStream.Activate(Object owningObject, GeneralAsyncDelegate asyncCallback)
   bij System.Net.ConnectionPool.GetConnection(Object owningObject, GeneralAsyncDelegate asyncCallback, Int32 creationTimeout)
   bij System.Net.FtpWebRequest.QueueOrCreateConnection()
   bij System.Net.FtpWebRequest.SubmitRequest(Boolean async)
   --- Einde van intern uitzonderingsstackpad ---
   bij System.Net.WebClient.UploadDataInternal(Uri address, String method, Byte[] data, WebRequest& request)
   bij System.Net.WebClient.UploadData(Uri address, String method, Byte[] data)
   bij System.Net.WebClient.UploadData(Uri address, Byte[] data)
   bij ProbeOrderPlacement.Order.OrderSubmit.SubmitOrder(XmlDocument xml) in H:\VSWorkspace\VSTS\Quantore\Probe\ProbeOrderPlacement\Order\OrderPlacement.cs:regel 28

也尝试了以下代码,但它抛出相同的异常(但在.GetRequestStream()处)

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("ftp://127.0.0.1/test.xml"));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Proxy = null;
request.UseBinary = true;
request.Credentials = new NetworkCredential("test", "test");
request.ContentLength = xmlBytes.Length;

//Upload the data
using(Stream requestStream = request.GetRequestStream()) {
    requestStream.Write(xmlBytes, 0, xmlBytes.Length);
}

异常: (英文:提供了无效的参数)

System.Net.WebException: Er is een ongeldig argument opgegeven ---> System.Net.Sockets.SocketException: Er is een ongeldig argument opgegeven
   bij System.Net.Sockets.Socket..ctor(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
   bij System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6)
   bij System.Net.PooledStream.Activate(Object owningObject, Boolean async, GeneralAsyncDelegate asyncCallback)
   bij System.Net.PooledStream.Activate(Object owningObject, GeneralAsyncDelegate asyncCallback)
   bij System.Net.ConnectionPool.GetConnection(Object owningObject, GeneralAsyncDelegate asyncCallback, Int32 creationTimeout)
   bij System.Net.FtpWebRequest.QueueOrCreateConnection()
   bij System.Net.FtpWebRequest.SubmitRequest(Boolean async)
   --- Einde van intern uitzonderingsstackpad ---
   bij System.Net.FtpWebRequest.GetRequestStream()
   bij ProbeOrderPlacement.Order.OrderSubmit.SubmitOrder(XmlDocument xml)

@mjwills 提供了一个无效的参数。我也更新了我的问题。 - Mark Baijens
1
如果你想得到帮助,就要发布实际的代码和相应的完整异常信息。 - Panagiotis Kanavos
3
这只是一个非常低级的问题,与您传递的参数无关,因为它们直到后来才被使用。底层操作系统功能(WSASocket)失败,似乎对创建TCP套接字不满意。当然,这种情况不应该发生。但是在网络编程中会出现问题,有太多垃圾挂在套接字上,声称可以保持您的机器安全和平稳运行。首先禁用已安装的防恶意软件产品,然后禁用任何类型的防火墙等其他内容。 - Hans Passant
1
我不知道导致这个问题的实际恶意软件,所以无法正确回答。这样的细节对未来的受害者非常重要。请创建自己的帖子分享你发现的内容,并将其标记为答案。 - Hans Passant
1
@HansPassant 我明白了。我自己回答了我的问题,但是很想把赏金分配给你。如果你提供任何形式的答案,我会这样做。 - Mark Baijens
显示剩余4条评论
4个回答

5
基于Hans Passant的评论,这是一个非常低级的错误,与您传递的参数无关,因为它们直到后来才会被使用。底层的操作系统函数(WSASocket)失败,因为创建TCP套接字似乎不成功。当然,这种情况不应该发生。但网络编码中经常出现问题,总有太多的垃圾挂在声称保护您机器安全并保持平稳运行的套接字上。首先禁用已安装的防恶意软件产品,其次是任何类型的防火墙等。
我发现对于我的情况,问题在于我的解决方案存储库位于公司提供给我的网络驱动器上。我最好的猜测是由于底层的安全措施导致上传失败,尽管我没有深入挖掘以证明这是实际情况。
在C驱动器上创建一个新的本地存储库就解决了这个问题。
所以建议那些遇到相同问题的读者,查看底层基础架构以克服问题。

0

看看 WebClient.UploadFile 方法。第二个参数是文件名。没有适用于byte[] 的重载。

试试这个

webclient.UploadData(uri, xmlfilename);

1
你说得没错,但那将是编译器错误,而不是运行时错误。这意味着 OP 没有提供 [mcve],你的答案无法解决手头的问题。 - CodeCaster
它返回一个字节数组,其中包含来自资源的响应正文。没有byte[]的重载。 - Azar Shaikh
@AzarShaikh,您链接了UploadFile()文档。我也尝试了这个函数(使用文件的绝对路径),但是它抛出了相同的错误。UploadData()接受byte[] - Mark Baijens
@MarkBaijens 再试一次 webclient.Credentials = new NetworkCredential("", "***");webclient.UploadFile("ftp://yourftp", "filename"); - Azar Shaikh
@AzarShaikh,正如我在问题中所述,我已经尝试过那个方法了。 - Mark Baijens
显示剩余2条评论

0

你的FTP网址似乎有误,请将代码更改为

byte[] xmlBytes = XmlDocumentToByteArray(xml);
WebClient webclient = new WebClient
{
      Proxy = null,
      Credentials = new NetworkCredential("test", "test")
};

Uri uri = new Uri("ftp://localhost/test.xml");
webclient.UploadData(uri, xmlBytes);

我也尝试了这种方法,并在我的问题中提到了它。它给出了相同的结果。 - Mark Baijens

0

我刚刚尝试了你的代码,除了读取XML文件并将其转换为 byte[] 之外没有进行任何更改,我能够成功上传文件而没有遇到任何问题。

enter image description here

由于您没有分享您的XML结构或读取和转换XML为byte[]的方法,我选择了最简单的XML形式和.NET中的开箱即用方法来读取和转换文件数据为byte[]

这是源文件source.xml中的XML文本:

<System>
    <E01></E01>
    <E02></E02>
    <E03></E03>
</System>

这是我的代码,用于在FTP服务器上读取-转换-上传source.xml:

        byte[] xmlBytes = File.ReadAllBytes ("D:\\source.xml");

        WebClient webclient = new WebClient ()
        {
            Proxy = null
        };

        Uri uri = new Uri ("ftp://ftp_user:ftp_password@localhost/test.xml");
        //Uri uri = new Uri("ftp://localhost/test.xml");
        webclient.UploadData (uri, xmlBytes);

注意:这是一个基于.NET Framework 4.7.1构建的Winforms应用程序。
如果您在XML结构或文件读取方式方面有任何特定要求,可以分享并进一步讨论。
或者,您可以在Github上分享一个精简版本的解决方案供其他人进行故障排除。
希望这能帮到您!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接