1

これは私の前のスレッドの続きと見なすことができます。

ファイル共有アプリケーションでいくつかの開発と修正を行いましたが、別の問題に直面しています。これはそれほど難しいことではないと思いますが、現在、これに取り組むための脳力が不足しているだけです. 私はこれがより良い方法でできると信じています。

これが私が受け取っているエラーのスクリーンショットです。

スクリーンショットでわかるように、FileName変数にはいくつかの値が含まれています。送信するファイルの名前です。お気づきの場合、変数には ello.cpp が含まれています。これはhello.cppでなければなりませhello.cppは、送信されるファイルの名前です。末尾の文字はファイルの内容です。末尾の文字はもう問題ではありません。これを正しく解決できる限り、変数に格納されるのはファイル名だけです。

エラーは、ネットワーク ストリームの読み取りプロセス中に発生します。私が達成したいのは、ネットワーク ストリームがログ メッセージでないときに読み取られないようにしたいということです。networkstream.readファイルの最初の文字を取らないように、どこかに置く必要があります。たぶん、ある種のフィルタリング?または、ログ メッセージとファイル名を取得できるコードを 1 つだけ持つことができれば、それは絶対に素晴らしいことです。ファイル名はバイナリライターを使用して送信されます。ネットワークストリームを使用してファイル名を取得しようとしましたが、うまくいきません。ここで何か不足していますか?

サーバー部分のコードは次のとおりです。

    Try

        While FileSharingStarted

            If CBool(ClientSocket.Available) Then

                Dim ByteData(ClientSocket.ReceiveBufferSize) As Byte

                'This reading of the stream here causes the problem. That's why the
                'file name isn't read properly. This reading part here is actually
                'intended for the logging part. What happens is that when the string
                'for the logging part is sent by the client side, this is being read
                'using this. But when a file is sent, it is read here in this part
                'that's why when the algorithm for retrieving the file name below
                'kicks in, the first letter of the file name is missing, and ruins
                'the whole thing.
                networkStream.Read(ByteData, 0, CInt(ClientSocket.ReceiveBufferSize))

                fileLogMessage = Encoding.ASCII.GetString(ByteData)
                Dim ConnectionStatus() As String
                ConnectionStatus = fileLogMessage.Split(CChar(" "))

                If fileLogMessage.Contains("is connected." & Environment.NewLine) Then

                    'Creates a log when the user connects.

                ElseIf fileLogMessage.Contains("is disconnected." & Environment.NewLine) Then

                   'Creates a log when the user disconnects.

                Else

                    'Algorithm for receiving the files.

                    Dim FileName, FilePath As String
                    Dim FileLength As Long

                    'This part here conflicts with the `networkstream.read` above
                    Dim binaryReader As New BinaryReader(ClientSocket.GetStream)
                    FileName = binaryReader.ReadString()
                    FileLength = binaryReader.ReadInt64()
                    FilePath = Path.Combine(System.Environment.CurrentDirectory & "\home", FileName)

                    Dim FileData(8092) As Byte
                    Dim TotalData As Long = 0
                    Dim ReadBytes As Integer = -1

                    Using fileStream As New FileStream(FilePath, FileMode.Create, FileAccess.Write)

                        FileSharingStatusBar.Panels.Item(1).Text = "Receiving file . . ."

                        Do Until TotalData = FileLength

                            If ReadBytes = 0 Then
                                fileStream.Close()
                                FileTransferInterrupted = True
                                Exit Do
                            Else
                                ReadBytes = ClientSocket.GetStream.Read(FileData, 0, FileData.Length())
                                fileStream.Write(FileData, 0, ReadBytes)
                                TotalData += ReadBytes
                            End If

                        Loop

                    End Using

                    If FileTransferInterrupted Then

                        MessageBox.Show("File transfer interrupted.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
                        FileSharingStatusBar.Panels.Item(1).Text = "Idle."

                    Else

                        MessageBox.Show("File received.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
                        FileSharingStatusBar.Panels.Item(1).Text = "Idle."

                    End If

                End If

            End If

        End While

クライアント側のコードは次のとおりです。

Try

        Dim fileInfo As New FileInfo(txtFilePath.Text)
        Dim binaryWriter As New BinaryWriter(fileClientSocket.GetStream())

        'Here's the part where it writes the file name on the
        'stream using the binary writer
        binaryWriter.Write(fileInfo.Name)
        binaryWriter.Write(fileInfo.Length)

        Using fileStream As New FileStream(txtFilePath.Text, IO.FileMode.Open, IO.FileAccess.Read)

            Dim FileData(8092) As Byte
            Dim ReadBytes As Integer = -1
            FileSharingStatusBar.Panels.Item(1).Text = "Sending file . . ."

            Do Until ReadBytes = 0

                If CBool(fileClientSocket.Available) Then

                    MessageBox.Show("File transfer interrupted.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
                    Exit Sub

                Else

                    ReadBytes = fileStream.Read(FileData, 0, FileData.Length)
                    fileClientSocket.GetStream.Write(FileData, 0, ReadBytes)

                End If

            Loop

        End Using

        txtFilePath.Text = ""
        MessageBox.Show("File sent.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
        FileSharingStatusBar.Panels.Item(1).Text = "Idle."

    Catch ex As Exception

        MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)

End Try

提案は高く評価されます。

前もって感謝します!:)

4

2 に答える 2

0

私はそれを解決する方法を考え出しました。仲間のプログラマーである Facebook での私の友人の提案の 1 つに感謝します。私がしたことは、サーバー部分にファイルを受信するように通知する文字列を送信することでした。今は大丈夫です。:)

また、特に SOAP に関するすべての努力と提案に対して、Steven Doggart に感謝したいと思います。

どうもありがとうございました!:)

于 2013-02-23T09:47:40.593 に答える
0

ネットワーク ストリーム内のすべてのデータを常に読み取り、それを通信バッファー/キューに追加することをお勧めします。キューにデータが追加されるたびに、キュー全体のデータを分析して、完全なメッセージが含まれているかどうかを確認します。その場合は、それらをキューから削除してから処理してください。たとえば、次のようなインターフェイスを実装するクラスを作成できます。

Public Interface IIncomingDataBuffer
    Sub Append(ByVal data() As Byte)
    Event MessageReceived As EventHandler(Of MessageEventArgs)
End Interface

メッセージが固定幅であるか、定義済みの区切り文字で区切られている場合、このような機能の実装が容易になります。また、各メッセージの先頭にヘッダー ブロックを配置することをお勧めします。ヘッダー ブロックには、少なくともメッセージ タイプの文字が含まれています。

于 2013-02-22T15:24:47.540 に答える