【发布时间】:2021-07-10 19:26:21
【问题描述】:
我目前编写了以下代码。 客户端和服务器端。 我想按需发送图像从服务器到客户端。图片将是来自服务器的截图,所以我的大小总是不同的。
发送第一张图片是一项圆满完成的任务。但是当我发送下一个时,图片框不会刷新。 通过调试我可以看到从服务器到客户端的字节成功通过。但是代码似乎只接收字节而不继续其余代码
“while”循环(客户端)的“注释”行似乎在调试中起作用,但我看不到结果,因为 程序卡在 while 循环中 我无法获得应用程序的前台窗口
我目前正在 Windows 中进行测试,但客户端将进行调整以在 android 上工作
服务器
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Socket client;
private void button2_Click(object sender, EventArgs e)
{
Bitmap bmp = TakingScreenshotEx1();
bmp.Save("1.jpeg", ImageFormat.Jpeg);
byte[] buffer = ReadImageFile("1.jpeg");
int v = client.Send(buffer, buffer.Length, SocketFlags.None);
Console.WriteLine("Image SENT!");
}
private Bitmap TakingScreenshotEx1()
{
//Create a new bitmap.
var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap.
var g = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner.
g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
return bmpScreenshot;
}
private void button1_Click(object sender, EventArgs e)
{
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(iep);
server.Listen(100);
Console.WriteLine("Waiting for client....");
client = server.Accept();
}
private static byte[] ReadImageFile(String img)
{
FileInfo fileinfo = new FileInfo(img);
byte[] buf = new byte[fileinfo.Length];
FileStream fs = new FileStream(img, FileMode.Open, FileAccess.Read);
fs.Read(buf, 0, buf.Length);
fs.Close();
GC.ReRegisterForFinalize(fileinfo);
GC.ReRegisterForFinalize(fs);
return buf;
}
}
客户
public Form1()
{
InitializeComponent();
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte[] buffer = new byte[1000000];
private void button1_Click(object sender, EventArgs e)
{
if(client.Connected != true)
client.Connect(iep);
// while (true)
// {
int v = client.Receive(buffer, buffer.Length, SocketFlags.None);
Console.WriteLine("Data Received!");
Stream stream = new MemoryStream(buffer);
var img = Bitmap.FromStream(stream);
pictureBox1.Image = img;
// }
}
【问题讨论】:
-
首先,为了让事情变得更容易,你应该使用
TcpClient和TcpServer。其次,套接字 I/O 与文件 I/O 完全不同。仅仅因为你打电话给Receive并不意味着你会得到整个数据包。服务器应该先发送数据的长度,然后发送实际数据。然后客户端将读取长度。那时它将从套接字读取,直到它具有所述数据的长度。这通常在循环中完成。 -
不清楚你在这里问什么。您已注释掉 似乎 有问题的部分,因此您的代码当然不会重现您所询问的问题。如果您取消注释
while (true),那么您将阻止 UI 线程,这是一个在此站点上仅被讨论过数千次的主题。你研究过吗?您应该异步读取数据。此外,虽然Bitmap.FromStream()可以准确确定它需要读取的字节数可能,但如果它偏离了一个字节,您的客户端将结束同步 ... -
... 正在发送数据。我不同意
TcpClient和TcpServer一定更好,但绝对必须注意前面评论中的其他信息;您的数据格式必须包含某种机制,以允许接收端点知道单个数据单元(例如图像)的开始和结束位置。 -
TcpClient 和 TcpServer 很棒,但它们不符合我的目标,因为它们无法在 android 中很好地处理。我发送的图像字节,它们都在接收时被读取。 @PeterDuniho 这听起来很有趣,但我不知道如何实现它。我将检查如何解决被阻止的 UI 并返回回复。我可以用什么代替
Bitmap.FromStream()?
标签: c# image winforms sockets stream