I'm making a webcam app that sends and receives small images. I have made it be able to send and receive, I tested on 127.0.0.1 and it worked fine, but now I'm using my own external IP address and it seems to send one image, receive one, then mess up, I get some sort of massive integer value in the image size, a minus value which leads it to crash, I think maybe the receive and send are running on their own, and are going out of sync somehow. I put a 1000ms delay before sending out each image and it was slow but working, as soon as I take the delay out, it messes up.
Here is the code :
// 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;
}
}
}
Read
doesn't necessarily read as many bytes as you ask for, just as many happen to be currently available -- you should actually check the return value to see how many it read. The documentation might help give you a better understanding.
You should add logic to keep reading until all of the image bytes have been read. A pseudo-code example:
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);
}