在.Net中通过TCP发送大文件

时间:2018-03-13 05:05:51

标签: .net sockets

我需要通过TCP发送大文件(> 50 meg)。我搜索了所有发布的问题和答案,但没有找到可行的解决方案。当我尝试发送时,我的发送程序发送一些数据包然后中止此错误:System.IO.IOException:无法将数据写入传输连接:已建立的连接被主机中的软件中止。

对于我的接收客户端,Listener.Pending()状态始终为false,因此它永远不会读取任何数据包。我的代码非常接近工作,但我需要一些鹰眼来看待它并提供帮助。

Public Sub SendTCPFile(Address As String, ModelName As String, FileName As String)
    Dim SendingBuffer As Byte() = Nothing
    Dim Client As TcpClient = Nothing
    Dim NetStream As NetworkStream = Nothing
    Dim BufferSize As Integer = 1024
    Try
        Client = New TcpClient(Address, PortNumber)
        NetStream = Client.GetStream()
        Dim FS As FileStream = New FileStream(FileName, FileMode.Open, FileAccess.Read)
        Dim NumberOfPackets As Integer = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(FS.Length) / Convert.ToDouble(BufferSize)))
        Dim CurrentPacketLength As Integer, TotalLength As Integer = CInt(FS.Length), counter As Integer = 0
        For i As Integer = 0 To NumberOfPackets - 1
            If TotalLength > BufferSize Then
                CurrentPacketLength = BufferSize
                TotalLength = TotalLength - CurrentPacketLength
            Else
                CurrentPacketLength = TotalLength
            End If
            SendingBuffer = New Byte(CurrentPacketLength) {}
           FS.Read(SendingBuffer, 0, CurrentPacketLength)
            NetStream.Write(SendingBuffer, 0, CInt(SendingBuffer.Length))
        Next
        FS.Close()
    Catch ex As Exception
        WriteLog("EXCEPTION in SendTCPFile")
    Finally
        NetStream.Close()
        Client.Close()
    End Try
End Sub

Public Sub ReceiveTCPFile(Address As String, ModelName As String)
    Dim Listener As TCPListener = Nothing
    Try
        Listener = New TcpListener(IPAddress.Any, PortNumber)
        Listener.Start()
    Catch ex As Exception
        WriteLog("EXCEPTION in SendTCPFile")
    EndTry
    Dim BufferSize As Integer = 1024
    ReceivingBuffer = New Byte(BufferSize) {}
    Dim BytesReceived As Integer
    While True
        Dim Client As TcpClient = Nothing
        Dim NetStream As NetworkStream = Nothing
        Try
             If Listener.Pending() Then
                  Client = Listener.AcceptTcpClient()
                  NetStream = Client.GetStream()
                  Dim FS As FileStream = New FileStream(SaveFileName, FileMode.OpenOrCreate, FileAccess.Write)
                  While (BytesReceived = NetStream.Read(ReceivingBuffer, 0, ReceivingBuffer.Length)) > 0
                       FS.Write(ReceivingBuffer, 0, BytesReceived)
                  End While
                  FS.Close()
                  NetStream.Close()
                  Client.Close()
            End If 'Listener.Pending
        Catch ex As Exception
            WriteLog("EXCEPTION in SendTCPFile")
            NetStream.Close()
        End Try
    End While
End Sub 'ReceiveTCPFile

1 个答案:

答案 0 :(得分:0)

您不需要在发件人方面计算NumberOfPackets。只需继续阅读FileStream,直到您到达EOF,发送您阅读的任何内容。就像你在接收方做的那样,当你继续阅读直到断开连接时,写入文件,无论你收到什么。

Public Sub SendTCPFile(Address As String, ModelName As String, FileName As String)
    Dim Client As TcpClient = Nothing
    Dim NetStream As NetworkStream = Nothing
    Try
        Client = New TcpClient(Address, PortNumber)
        NetStream = Client.GetStream()
        Dim FS As FileStream = New FileStream(FileName, FileMode.Open, FileAccess.Read)
        Dim BufferSize As Integer = 1024
        Dim SendingBuffer As Byte() = New Byte(BufferSize) {}
        Dim PacketLength As Integer = 0
        While (PacketLength = FS.Read(SendingBuffer, 0, SendingBuffer.Length)) > 0
          NetStream.Write(SendingBuffer, 0, PacketLength)
        End While
        FS.Close()
    Catch ex As Exception
        WriteLog("EXCEPTION in SendTCPFile")
    Finally
        NetStream.Close()
        Client.Close()
    End Try
End Sub

对于您的Listener.Pending问题,这只能意味着您的客户端从不尝试连接到服务器,因此服务器无法接受连接。在服务器接受连接之前,您无法将数据发送到服务器。如果TcpClient构造函数无法建立连接,则会引发异常。因此,如果构造函数没有失败,但Pending始终为false,则客户端必须连接到除您自己以外的其他服务器。