Question

This can be considered as a continuation of my previous thread.

I made some developments and fixed things on my file sharing application, but now I'm facing another problem. This one's not that difficult I guess, its just that I'm currently running out of brain power to tackle this one. I believe this can be done in a better way.

Here's a screenshot of the error I'm receiving.

As you can see on the screenshot, the FileName variable has some values in it. Its the name of the file I'm sending. If you've notice, the variable contains ello.cpp, it must be hello.cpp. hello.cpp is the name of the file being sent. The trailing characters were the contents of the file. The trailing characters is not a problem anymore, as long as I can solve this one correctly, the file name will be the only one stored on the variable.

The error occurs during the reading process of the network stream. What I want to achieve is that, I want to prevent the network stream from reading when it is not a log message. I need to put the networkstream.read somewhere so that it will not take the first letter of the file. Maybe some kind of filtering? Or if it is possible to have only one code that can get the log message and the file name, that would be absolutely great. The file name is sent using the binary writer, I tried using the network stream to retrieve the file name, but it doesn't work. Am I missing something here?

Here's the code on the server part.

    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

Here's the code for the client side.

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

Suggestions will be highly appreciated.

Thanks in advance! :)

Was it helpful?

Solution 2

I figured out how to solve it. Thanks to one of my friend's suggestion in facebook, a fellow programmer. What I did, was send some string that signals the server part to receive the file. It's all good now. :)

I would like to also acknowledge Steven Doggart for all of his the efforts and suggestions, especially about the SOAP.

Thanks a lot good sir! :)

OTHER TIPS

I would recommend always reading all of the data in the network stream and appending it to communication buffer/queue. Each time more data is appended to the queue, analyze the data in the entire queue to see if it contains any complete messages. If so, remove them from the queue and then process them. For instance, you could create a class that implements an interface like this:

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

It will be easier to implement such functionality if messages are either fixed width or separated by a predefined delimiter. Also, I'd recommend having a header block at the beginning of each message which contains, if nothing else, a message type character.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top