我一直在思考为什么会发生这种情况,它会很好地运行几次,但它会随机收到一个奇数的长度(例如-123456,或者它&& #39;将收到0)。
然后,当它从流中创建一个图像时,它不能,因为长度是错误的。有时长度值看起来像一个正常值,但是当它生成图像时我仍然会得到参数异常。
编辑:我也随机收到" len"导致Out Of Memory Exception的对象,但发送方从不发送任何与该数字一样大的内容,因此我不明白该数字的来源。
这是接收代码:
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()");
}
}
}
发送代码:
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()");
}
}
}
答案 0 :(得分:1)
您假设Read/Receive
完全返回您想要的数据量。事实并非如此。它最多返回 ,并且至少返回一个字节。调整您的代码以处理这一事实。例如,通过使用BinaryReader
或读取循环,直到获得所需的字节数。
更好的是:停止使用套接字。使用更高级别的东西,如HTTP或Web服务。套接字在大多数情况下是错误的解决方案。