C# 通过tcp c接收图像时随机获取参数异常和内存不足异常#
我一直在绞尽脑汁想为什么会发生这种情况,它会运行好几次,但它会随机地以奇数形式接收长度(-123456,例如,它会以0形式接收) 然后,当它从流中生成图像时,它不能,因为长度是错误的。有时,长度值看起来像正常值,但在生成图像时,我仍然会得到参数异常 编辑:我还随机接收到“len”对象的大数字,这会导致内存不足异常,但发送端从未发送过如此大的数字,因此我不知道该数字来自何处 这是接收代码:C# 通过tcp c接收图像时随机获取参数异常和内存不足异常#,c#,image,tcp,argumentexception,C#,Image,Tcp,Argumentexception,我一直在绞尽脑汁想为什么会发生这种情况,它会运行好几次,但它会随机地以奇数形式接收长度(-123456,例如,它会以0形式接收) 然后,当它从流中生成图像时,它不能,因为长度是错误的。有时,长度值看起来像正常值,但在生成图像时,我仍然会得到参数异常 编辑:我还随机接收到“len”对象的大数字,这会导致内存不足异常,但发送端从未发送过如此大的数字,因此我不知道该数字来自何处 这是接收代码: public void ReceiveSS() { bool firstTi
public void ReceiveSS()
{
bool firstTimeRun = true;
TcpListener ssTcpListener = new TcpListener(IPAddress.Any, 63000);
TcpClient tcpReceiver = new TcpClient();
ssTcpListener.Start();
tcpReceiver = new TcpClient();
if (!uPnPWorks)
{
try
{
Console.WriteLine(contactIP + " " + port);
tcpReceiver.Connect(contactIP.ToString(), port);
}
catch (Exception)
{
}
}
else
{
tcpReceiver = ssTcpListener.AcceptTcpClient();
}
while (!ssStop)
{
try
{
//Start listening for connection.
if (tcpReceiver.Connected)
{
if (firstTimeRun)
{
//TCP connected. Receive images from contact.
NetworkStream receivedNs = new NetworkStream(tcpReceiver.Client);
BinaryReader br = new BinaryReader(receivedNs);
byte[] lenOfImage = new byte[4];
br.Read(lenOfImage, 0, 4);
int len = (int)(lenOfImage[0] << 24) | (int)(lenOfImage[1] << 16) | (int)(lenOfImage[2] << 8) | lenOfImage[3];
Console.WriteLine(len);
byte[] receivedData = new byte[len];
br.Read(receivedData, 0, receivedData.Length);
MemoryStream ms = new MemoryStream(receivedData, 0, receivedData.Length);
ms.Seek(0, SeekOrigin.Begin);
receivedNs.Flush();
Bitmap image = new Bitmap(ms);
receivedImage = image;
//Put image into picturebox.
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate() { pboScreenShare.Image = image; }));
}
else { pboScreenShare.Image = image; }
//br.Close();
firstTimeRun = false;
}
else if (!firstTimeRun)
{
//TCP connected. Receive images from contact.
NetworkStream receivedNs = new NetworkStream(tcpReceiver.Client);
BinaryReader br = new BinaryReader(receivedNs);
byte[] lenOfImage = new byte[4];
br.Read(lenOfImage, 0, 4);
int len = (int)(lenOfImage[0] << 24) | (int)(lenOfImage[1] << 16) | (int)(lenOfImage[2] << 8) | lenOfImage[3];
try
{
MemoryStream ms = new MemoryStream();
if (len > 0)
{
byte[] receivedData = new byte[len];
br.Read(receivedData, 0, receivedData.Length);
ms = new MemoryStream(receivedData, 0, receivedData.Length);
ms.Seek(0, SeekOrigin.Begin);
}
receivedNs.Flush();
receivedImage2 = new Bitmap(ms); //Where I get the random argument exception
receivedImage2.MakeTransparent(Color.Pink);
Bitmap overlayedImage = new Bitmap(receivedImage.Width, receivedImage.Height);
using (Graphics gr = Graphics.FromImage(overlayedImage))
{
gr.DrawImage(receivedImage, new Point(0, 0));
gr.DrawImage(receivedImage2, new Point(0, 0));
}
//Put image into picturebox.
this.Invoke(new MethodInvoker(delegate() { pboScreenShare.Image = overlayedImage; }));
receivedImage2.Dispose();
receivedImage = overlayedImage;
//br.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + " Getting image");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString() + " ReceiveSS()");
}
}
}
您假设
Read/Receive
返回的数据量正好是您想要的数据量。事实并非如此。它最多返回那么多,至少返回一个字节。调整代码以处理这一事实。例如,使用BinaryReader
或循环读取,直到获得所需的字节数
更好的方法是:停止使用套接字。使用更高级的东西,比如HTTP或web服务。套接字在大多数情况下都是错误的解决方案。您好,我使用的是BinaryReader,它仍然没有返回适当的数量。我将尝试你提到的循环阅读。而使用http services.BinaryReader.Read只是将调用中继到底层流。不过,ReadBytes会读取您想要的字节数(如果可用)。谢谢,BinaryRead.ReadBytes工作得非常好!我会投票支持你,但我的名声太低了(
private void SendSS()
{
int cursorX = 0;
int cursorY = 0;
TcpListener listener = new TcpListener(IPAddress.Any, 63001);
listener.Start();
tcpClient = new TcpClient();
if (uPnPWorks)
{
tcpClient = listener.AcceptTcpClient();
}
else
{
try
{
tcpClient.Connect(contactIP, 63000);
}
catch (Exception)
{
}
}
bool firstTimeRun = true;
while (!ssStop)
{
try
{
if (tcpClient.Connected)
{
//Connected. Capture screen image.
if (firstTimeRun)
{
MemoryStream ssmemStream = new MemoryStream();
screenShotBMP = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Bitmap cursorBMP = CaptureCursor(ref cursorX, ref cursorY);
Graphics graphics = Graphics.FromImage(screenShotBMP as Image);
graphics.CopyFromScreen(0, 0, 0, 0, screenShotBMP.Size);
if (cursorBMP != null)
{
using (Graphics g = Graphics.FromImage(screenShotBMP))
{
Rectangle r = new Rectangle(cursorX, cursorY, cursorBMP.Width, cursorBMP.Height);
g.DrawImage(cursorBMP, r);
}
}
Bitmap saveScreenShot = screenShotBMP;
saveScreenShot.Save(ssmemStream, ImageFormat.Png);
NetworkStream ns = tcpClient.GetStream();
//Convert image to data.
BinaryWriter bw = new BinaryWriter(ns);
byte[] bytesToSend = ssmemStream.ToArray();
byte[] imageLen = new byte[4];
int len = bytesToSend.Length;
imageLen[0] = (byte)((len & 0xff000000) >> 24);
imageLen[1] = (byte)((len & 0x00ff0000) >> 16);
imageLen[2] = (byte)((len & 0x0000ff00) >> 8);
imageLen[3] = (byte)(len & 0xff);
ns.Write(imageLen, 0, 4);
ns.Write(bytesToSend, 0, bytesToSend.Length);
Console.WriteLine(bytesToSend.Length);
ns.Flush();
//bw.Close();
firstTimeRun = false;
}
else if (!firstTimeRun)
{
MemoryStream ssmemStream = new MemoryStream();
screenShotBMP2 = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Bitmap cursorBMP = CaptureCursor(ref cursorX, ref cursorY);
Graphics graphics = Graphics.FromImage(screenShotBMP2 as Image);
graphics.CopyFromScreen(0, 0, 0, 0, screenShotBMP2.Size);
if (cursorBMP != null)
{
using (Graphics g = Graphics.FromImage(screenShotBMP2))
{
Rectangle r = new Rectangle(cursorX, cursorY, cursorBMP.Width, cursorBMP.Height);
g.DrawImage(cursorBMP, r);
}
}
diffImage = ImageTool.GetDifferenceImage(screenShotBMP, screenShotBMP2, Color.Pink);
diffImage.Save(ssmemStream, ImageFormat.Png);
try
{
NetworkStream ns = tcpClient.GetStream();
//Convert image to data.
BinaryWriter bw = new BinaryWriter(ns);
byte[] bytesToSend = ssmemStream.ToArray();
byte[] imageLen = new byte[4];
int len = bytesToSend.Length;
Console.WriteLine(len);
imageLen[0] = (byte)((len & 0xff000000) >> 24);
imageLen[1] = (byte)((len & 0x00ff0000) >> 16);
imageLen[2] = (byte)((len & 0x0000ff00) >> 8);
imageLen[3] = (byte)(len & 0xff);
ns.Write(imageLen, 0, 4);
ns.Write(bytesToSend, 0, bytesToSend.Length);
Console.WriteLine(bytesToSend.Length);
ns.Flush();
//bw.Close();
}
catch
{
Console.WriteLine("iox exception");
}
screenShotBMP = screenShotBMP2;
}
}
}
catch (SocketException sockEx)
{
Console.WriteLine(sockEx.Message + " SendSS()");
}
}
}