【问题标题】:TCP/IP File Transfer in .NET.NET 中的 TCP/IP 文件传输
【发布时间】:2016-07-25 07:32:13
【问题描述】:

我正在尝试在 VB.NET 应用程序中通过 TCP/IP 传输文件,我对传输文件的大小有疑问,这里是代码:

服务器:

Imports System.Net.Sockets
Imports System.Text
Imports System.Net
Imports System.ComponentModel
Class MainWindow
    Dim Timer As New Stopwatch
    Dim LocalAddr As IPAddress
    Dim ServerSocket As TcpListener
    Dim RequestCount As Integer
    Dim ClientSocket As TcpClient
    Dim BW As New BackgroundWorker With {.WorkerSupportsCancellation = True}
    Dim BWAccept As New BackgroundWorker With {.WorkerSupportsCancellation = True}
    Dim FileStreamer As New      System.IO.FileStream("C:\Users\m_shahgholi\Desktop\New folder\test.dcm", IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.ReadWrite)

   Private Sub DoWorker(sender As Object, e As System.ComponentModel.DoWorkEventArgs)

      While (True)
        Try
            RequestCount = RequestCount + 1

            Dim networkStream As NetworkStream = ClientSocket.GetStream()


            Dim bytesFrom(ClientSocket.ReceiveBufferSize) As Byte
            networkStream.Read(bytesFrom, 0, CInt(ClientSocket.ReceiveBufferSize))


            'IO.File.WriteAllBytes("C:\temp\1.dcm", bytesFrom)
            Me.Dispatcher.Invoke(Sub()
                                     If ClientSocket.Available <> 0 Then
                                         TextBoxClientBufferSize.Text =  ClientSocket.Available.ToString
                                     End If


                                     FileStreamer.Write(bytesFrom, 0,  CInt(ClientSocket.ReceiveBufferSize))

                                 End Sub)
            'Dim dataFromClient As String = System.Text.Encoding.ASCII.GetString(bytesFrom)
            'dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"))
            'msg("Data from client -  " + dataFromClient)
            Dim serverResponse As String = "Server response " +  Convert.ToString(RequestCount) + "$"
            Dim sendBytes As Byte() = Encoding.UTF8.GetBytes(serverResponse)
            networkStream.Write(sendBytes, 0, sendBytes.Length)
            networkStream.Flush()
            msg(serverResponse)
            'networkStream.Close()
        Catch ex As Exception
            Exit While
        End Try
    End While

End Sub

Private Sub CompleteWorker(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs)

    ClientSocket.Close()
    ServerSocket.Stop()
    msg("exit")
    StackPanelClient.Visibility = Windows.Visibility.Collapsed
    Timer.Stop()

    TextBoxClientBufferSize.Text = Timer.Elapsed.ToString
    FileStreamer.Close()
End Sub
Sub msg(ByVal mesg As String)
    mesg.Trim()
    Me.Dispatcher.Invoke(
        Sub()
            RichTextBoxRecivedText.AppendText(mesg + vbCrLf)
            RichTextBoxRecivedText.ScrollToEnd()
        End Sub)
End Sub

   Private Sub ButtonStart_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles ButtonStart.Click
    TextBoxServerIP.Text = System.Net.Dns.GetHostByName(Dns.GetHostName()).AddressList(0).ToString()
    LocalAddr = IPAddress.Parse(TextBoxServerIP.Text)
    ServerSocket = New TcpListener(LocalAddr, 8888)

    ServerSocket.Start()
    msg("Server Started")
    WaitForClientProgressIndicator.Visibility = Windows.Visibility.Visible
    LabelServerIP.Visibility = Windows.Visibility.Visible
    TextBoxServerIP.Visibility = Windows.Visibility.Visible
    WaitForClientProgressIndicator.Start()
    StackPanelServer.Background = Brushes.Red
    AddHandler BWAccept.DoWork, AddressOf AcceptDoWorker
    AddHandler BWAccept.RunWorkerCompleted, AddressOf AcceptCompleteWorker
    BWAccept.RunWorkerAsync()
End Sub

Private Sub AcceptDoWorker(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
    ClientSocket = ServerSocket.AcceptTcpClient
    ServerSocket.Server.ReceiveBufferSize = 8192 * 2
    ClientSocket.ReceiveBufferSize = 8192 * 2

End Sub

Private Sub AcceptCompleteWorker(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs)
    msg("Accept connection from client")
    Me.Dispatcher.Invoke(Sub() TextBoxClientBufferSize.Text = ClientSocket.ReceiveBufferSize)
    RequestCount = 0
    RichTextBoxRecivedText.Background = Brushes.Black
    RichTextBoxRecivedText.Foreground = Brushes.WhiteSmoke
    WaitForClientProgressIndicator.Visibility = Windows.Visibility.Collapsed
    WaitForClientProgressIndicator.End()
    ButtonStart.Visibility = Windows.Visibility.Collapsed
    ButtonStop.Visibility = Windows.Visibility.Visible
    AddHandler BW.DoWork, AddressOf DoWorker
    AddHandler BW.RunWorkerCompleted, AddressOf CompleteWorker
    Timer.Start()
    BW.RunWorkerAsync()
    TextBoxClientIP.Text = DirectCast(ClientSocket.Client.RemoteEndPoint, IPEndPoint).Address.ToString
    StackPanelClient.Visibility = Windows.Visibility.Visible
    StackPanelServer.Background = Brushes.WhiteSmoke
End Sub

Private Sub ButtonStop_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles ButtonStop.Click
    ClientSocket.Close()
    ServerSocket.Stop()
    msg("Server Stopped")
    ButtonStart.Visibility = Windows.Visibility.Visible
    ButtonStop.Visibility = Windows.Visibility.Collapsed
    BW.CancelAsync()
    BWAccept.CancelAsync()
    StackPanelClient.Visibility = Windows.Visibility.Collapsed
    StackPanelServer.Visibility = Windows.Visibility.Collapsed
End Sub

End Class

客户:

Imports System.Net.Sockets
Imports System.IO

Class MainWindow
    Dim networkStream As NetworkStream

    Private Sub ButtonStart_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles ButtonStart.Click
        Dim tcpClnt As New System.Net.Sockets.TcpClient
        Dim port As Integer = 8888
        Try
            tcpClnt.Connect(TextBoxServerIP.Text, port)
            networkStream = tcpClnt.GetStream()
        Catch ex As Exception
            MsgBox(ex.ToString())
        End Try
    End Sub

    Private Sub ButtonSend_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles ButtonSend.Click
        Dim fs As FileStream
        fs = New    FileStream("D:\Software\NIC\DCM\Series1\10.129.1125.111.1246.1101.20150106081616.1.dcm", FileMode.Open)
        Dim objReader As New BinaryReader(fs)
        Dim send() As Byte = objReader.ReadBytes(fs.Length)
        networkStream.Write(send, 0, send.Length)
        objReader.Close()
        fs.Close()
    End Sub

    Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        TextBoxServerIP.Text = "192.168.1.106"
    End Sub
End Class

应用程序可以运行,但出现错误。 假设一个大小为 1000 字节的文件,在此代码中,缓冲区大小为 16KB。传输的文件是 16KB 而不是 1000 字节,并且在文件末尾添加了一些 0。 我必须做些什么来纠正?

【问题讨论】:

  • 你忽略了networkStream.Read()的返回值。
  • @CodeCaster:您能告诉我更多我必须做些什么来更正吗?
  • 当然。阅读NetworkStream.Read() 的文档 :) 很抱歉,但你不会找到很多愿意帮助你的人。 TCP 是低级的,很难正确处理——你真的需要知道你在做什么。

标签: .net vb.net sockets tcpclient tcp-ip


【解决方案1】:

基本上,您的 NetworkStream.Read() 只是读取缓冲区大小并处理该数据,而忽略仍在缓冲区中的文件的其余部分。您需要在循环中多次调用 Read() 以获取所有内容并将其组合在一起。 Read() 返回读取的字节数 - 当它为 0 时,您已收到所有内容。

正如 Luaan 建议的那样 - 阅读文档:https://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.read(v=vs.110).aspx

很难做到正确,尝试找到一个可以使这更容易的库。我喜欢Winsock.Net - 文档不多,但相当有效 - 还有一个 SendFile 方法。

【讨论】:

    【解决方案2】:

    感谢 Jochen Arndt (http://www.codeproject.com/script/Membership/View.aspx?mid=2225683) 这是答案 我必须使用 NetworkStream.Read() 返回的实际接收到的字节数:

    Dim numberOfBytesRead As Integer = 0
    numberOfBytesRead = networkStream.Read(bytesFrom, 0, bytesFrom.Length)
    '...
    FileStreamer.Write(bytesFrom, 0,  numberOfBytesRead)
    

    【讨论】:

      猜你喜欢
      • 2018-05-14
      • 2011-05-25
      • 2011-02-27
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      相关资源
      最近更新 更多