vb.net - Visual Basic TCP 数据损坏
问题描述
我有一个程序使用 TCP 进行客户端和服务器之间的通信。客户端发送一个 BMP 图像的字节数组。侦听器以块的形式读取字节并将字节连接在一起以获取图像。当服务器/侦听器接收到图像时,它几乎在中途损坏。
当使用 localhost 在我的计算机上进行测试时,损坏的可能性较小(更大的字节数组大小 = 更多的损坏),但是当通过互联网时,无论大小如何,它都有 99% 的时间被损坏。我也尝试过拆分字节数组并将其分块发送到服务器,这似乎修复了本地主机上的损坏,但在互联网上仍然相同。
有人可以告诉我我在这里做错了什么吗?
在计时器中运行的监听器代码:
If Listener.Pending = True Then
Client = Listener.AcceptTcpClient()
Message = ""
Dim ClientNetworkStream As NetworkStream = Client.GetStream
ReDim ReadBytes(-1)
If ClientNetworkStream.CanRead = True Then
Dim ReadBuffer(65535) As Byte
Dim NumberOfBytesRead As Integer = 0
Do
NumberOfBytesRead = ClientNetworkStream.Read(ReadBuffer, 0, ReadBuffer.Length)
If Not NumberOfBytesRead = 0 Then
If Not NumberOfBytesRead = -1 Then
ReadBytes = AppendByteArrays(ReadBytes, ReadBuffer, NumberOfBytesRead)
If ConvoOngoing = False Then
ReDim CurrentConvoBytes(-1)
ConvoOngoing = True
CurrentConvoBytes = ReadBytes
Else
CurrentConvoBytes = AppendByteArrays(CurrentConvoBytes, ReadBytes)
End If
End If
End If
Loop While ClientNetworkStream.DataAvailable
If ClientNetworkStream.DataAvailable = False Then
If ConvoOngoing = True Then
If ReadBytes.Length > 0 Then
CurrentConvoBytes = AppendByteArrays(CurrentConvoBytes, ReadBytes)
End If
ConvoOngoing = False
PictureBox1.Image = ConvertByteArrayToBMP(CurrentConvoBytes)
End If
End If
End If
End If
这是发件人代码:
Private Sub SendWhole(ByVal BytesToSend() As Byte, ByVal Optional isFile As Boolean = False)
Client = New TcpClient(TextBox2.Text, TextBox3.Text)
Dim ClientStream As NetworkStream = Client.GetStream
ClientStream.Write(BytesToSend, 0, BytesToSend.Length)
ClientStream.Close()
End Sub
以及代码中使用的 AppendByteArrays 代码:
Public Function AppendByteArrays(ByVal OriginalArray As Byte(), ByVal ArrayToAppend As Byte(), ByVal Optional AmountOfValuesToAdd As Integer = -1) As Byte()
Dim IndexToStart As Integer = OriginalArray.Length
Dim Modifier As Integer = 0
If Not AmountOfValuesToAdd = -1 Then
Modifier = AmountOfValuesToAdd - 1
Else
Modifier = -1
End If
If Modifier = -1 Then
ReDim Preserve OriginalArray((OriginalArray.Length) + (ArrayToAppend.Length - 1))
For i = 0 To ArrayToAppend.Length - 1
OriginalArray(IndexToStart + i) = ArrayToAppend(i)
Next
Else
ReDim Preserve OriginalArray((OriginalArray.Length) + Modifier)
For i = 0 To Modifier
OriginalArray(IndexToStart + i) = ArrayToAppend(i)
Next
End If
Return OriginalArray
End Function
编辑:这是我似乎无法弄清楚数学的地方
If Listener.Pending = True Then
Client = Listener.AcceptTcpClient()
Dim ClientNetworkStream As NetworkStream = Client.GetStream
ReDim ReadBytes(-1)
If ClientNetworkStream.CanRead = True Then
Dim ReadBuffer(65535) As Byte
Dim NumberOfBytesRead As Integer = 0
Do
NumberOfBytesRead = ClientNetworkStream.Read(ReadBuffer, 0, ReadBuffer.Length)
If Not NumberOfBytesRead = 0 Then
If Not NumberOfBytesRead = -1 Then
If ReadingPacket = False Then
If PacketHasLeftOvers = True Then
PacketHasLeftOvers = False
ReadBuffer = AppendByteArrays(PacketLeftOvers, ReadBuffer)
ReDim PacketLeftOvers(-1)
End If
ReadingPacket = True
PacketToReadSize = BitConverter.ToInt32(ReadBuffer, 0)
PacketType = ReadBuffer(4)
ReDim CurrentConvoBytes(-1)
ReadBytes = AppendByteArrays(ReadBytes, ReadBuffer.Skip(5).ToArray, NumberOfBytesRead - 5)
CurrentConvoBytes = ReadBytes
PacketReadSize = ReadBytes.Length - 1
If PacketReadSize = PacketToReadSize Then
'Check if already finished reading
PictureBox1.Image = ConvertByteArrayToBMP(CurrentConvoBytes)
PacketReadSize = 0
ReadingPacket = False
End If
Else
Dim PacketScore As Integer = PacketReadSize + NumberOfBytesRead
If PacketScore < PacketToReadSize Then
ReadBytes = AppendByteArrays(ReadBytes, ReadBuffer, NumberOfBytesRead)
CurrentConvoBytes = AppendByteArrays(CurrentConvoBytes, ReadBytes)
PacketReadSize += ReadBytes.Length - 1
ElseIf PacketScore > PacketToReadSize Then
ReadBytes = AppendByteArrays(ReadBytes, ReadBuffer, NumberOfBytesRead - (PacketToReadSize - PacketReadSize))
CurrentConvoBytes = AppendByteArrays(CurrentConvoBytes, ReadBytes)
PacketHasLeftOvers = True
PacketLeftOvers = ReadBuffer.Skip(PacketToReadSize - PacketReadSize).ToArray
PictureBox1.Image = ConvertByteArrayToBMP(CurrentConvoBytes)
PacketReadSize = 0
ReadingPacket = False
ElseIf PacketScore = PacketToReadSize Then
ReadBytes = AppendByteArrays(ReadBytes, ReadBuffer, NumberOfBytesRead)
CurrentConvoBytes = AppendByteArrays(CurrentConvoBytes, ReadBytes)
PictureBox1.Image = ConvertByteArrayToBMP(CurrentConvoBytes)
PacketReadSize = 0
ReadingPacket = False
End If
End If
End If
Else
Throw New Exception
End If
Loop While ClientNetworkStream.DataAvailable
End If
End If
解决方案
推荐阅读
- powershell - 如果属性名称是整数,为什么我不能点引用哈希表键的值属性
- python - Python - 不确定我是通过 FTP 还是 SFTP 连接到服务器
- firebase - 我在尝试 this.in 时遇到此错误。以前的版本我用这种方式构建它,但我现在不能。颤振快照映射
- eclipse - .pack 文件的 Eclipse 问题
- javascript - v-for 循环一次选择多个项目并在选择索引时更改图像
- php - 复制教程代码后,PHP 表单验证不起作用
- c++ - 有没有办法将分配的对象实际移动到 std::list
- php - 分页链接不显示所有页面
- linux-kernel - 用户空间看不到 MMAP 缓冲区内核写入
- python-3.x - AWS Lambda 返回 Unable to import module 'main': No module named 'main' when modules are there