TCP数据包发送错误
本文关键字:错误 数据包 TCP | 更新日期: 2023-09-27 18:20:07
我正在制作一个发送和接收小图像的网络摄像头应用程序。我已经使它能够发送和接收,我在127.0.0.1上进行了测试,它运行良好,但现在我使用自己的外部IP地址,它似乎发送一个图像,接收一个,然后出错,我在图像大小中得到了某种巨大的整数值,一个导致它崩溃的负值,我认为接收和发送可能是独立运行的,并且不知何故会不同步。在发送每张图像之前,我设置了1000毫秒的延迟,虽然速度很慢,但可以工作,我一取消延迟,它就一团糟。
这是代码:
// This sends.
private void NewFrameReceived(object sender, NewFrameEventArgs e)
{
Bitmap img = (Bitmap)e.Frame.Clone();
byte[] imgBytes = EncodeToJpeg(img, 25).ToArray();
if (_tcpOut.Connected)
{
NetworkStream ns = _tcpOut.GetStream();
if (ns.CanWrite)
{
System.Threading.Thread.Sleep(500);
ns.Write(BitConverter.GetBytes(imgBytes.Length), 0, 4);
ns.Write(imgBytes, 0, imgBytes.Length);
}
}
}
// This receives.
private void listeningThread_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
// start listening for connections
_tcpIn = new TcpListener(IPAddress.Any, 54321);
_tcpIn.Start();
TcpClient _inClient = _tcpIn.AcceptTcpClient();
while (true)
{
NetworkStream ns = _inClient.GetStream();
if (ns.CanRead && ns.DataAvailable)
{
Byte[] imgSizeBytes = new Byte[4];
ns.Read(imgSizeBytes, 0, 4);
int imgSize = BitConverter.ToInt32(imgSizeBytes, 0);
Byte[] imgBytes = new Byte[imgSize]; <-- ERROR, GET CRAZY LARGE VALUE
ns.Read(imgBytes, 0, imgSize);
MemoryStream ms = new MemoryStream(imgBytes);
Image img = Image.FromStream(ms);
picVideo.Image = img;
}
}
}
您需要重新思考一下。。。。。数据可以以不同的分组到达。您的读取功能将只读取可用的内容。这将导致您的系统失去同步。
我会为图像建立一个小协议,这样我就可以随时知道图像的开始和结束在我的数据流中的位置。
你不必这么做,但这会让生活变得更轻松,你可以完全通过一个简单的状态机来实现,它知道通过接收图像它已经走了多远。但是,任何不遵守发送图像的行为(例如,流中多出1个字节)都可能导致图像永远不同步。
Read
不一定能读取您要求的那么多字节,就像当前碰巧有多少字节一样——您实际上应该检查返回值,看看它读取了多少字节。文档可能有助于您更好地理解。
您应该添加逻辑以保持读取,直到读取完所有图像字节。伪代码示例:
total_bytes_read = 0;
while (total_bytes_read != total_bytes_needed)
{
bytes_left_to_read = total_bytes_needed - total_bytes_read;
total_bytes_read += read(buffer, total_bytes_read, bytes_left_to_read);
}