這可以看作是我以前thread.Receving數據從二進制作家網絡流
我做了我的文件共享應用的一些發展和固定的東西的延續,但我現在面臨的另一個問題。我猜這不是那麼難,只是我現在用腦力來解決這個問題。我相信這可以以更好的方式完成。
下面是我收到的錯誤的屏幕截圖。
正如你可以在截圖中看到,該FileName
變量中有一定價值。它是我發送的文件的名稱。如果您注意到,變量包含ello.cpp,它必須是hello.cpp。 hello.cpp是要發送的文件的名稱。尾隨的字符是文件的內容。尾隨字符不再是問題,只要我能正確解決這個問題,文件名將是唯一存儲在變量中的文件名。
錯誤發生在網絡流的讀取過程中。我想要實現的是,我想阻止網絡流在不是日誌消息時讀取。我需要將networkstream.read
放在某個位置,以便它不會佔用文件的第一個字母。也許某種過濾?或者如果可能只有一個代碼可以獲取日誌消息和文件名,那將非常棒。文件名是使用二進制編寫器發送的,我嘗試使用網絡流來檢索文件名,但它不起作用。我在這裏錯過了什麼嗎?
以下是服務器部分的代碼。
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
建議將不勝感激。
在此先感謝! :)
謝謝你的回覆。這似乎是一個不錯的主意。但事情是,我只能這樣做,如果我能夠得到正在發送的文件的文件名。只要我無法檢索網絡流上的文件名(因爲它是用二進制寫入器編寫的),我不能這樣做,因爲我不知道如何在寫入時使用網絡流檢索文件名二進制作家。此外,我只需要對代碼進行適當的重構,特別是'networkstream.read'部分,以便在發送文件時不會發生干擾。 – 2013-02-22 15:38:40
那麼,據我瞭解,你正在發送兩種不同類型的消息:日誌消息和文件傳輸消息。在日誌消息中,您只有一個有效負載字段:要記錄的文本。但在文件傳輸消息中,您有三個有效負載字段:文件名,文件大小和文件內容。因此,您不僅需要定義如何確定每封郵件的開始和結束位置,而且還需要定義如何確定郵件中每個字段的開始和結束位置。 – 2013-02-22 16:05:38
你在本質上做的是定義你自己的協議。這絕不是一個不可能完成的任務,但它是設計中非常關鍵的一步,不能簡單地跳過或掩蓋。如果你不想花時間去設計一個好的協議,我建議你只使用一個已經存在的協議,比如SOAP。 .NET框架內置了用於處理SOAP的類,而Visual Studio IDE甚至提供了方便的WCF和ASMX Web服務工具,用於開發基於SOAP的應用程序的客戶端和服務器端。 – 2013-02-22 16:07:44