极客秀
搜索

.NET MAUI的Android WiFi图传开发(3)——Android设备接收TCP信息并显示图片

这几天折磨死我了,因为这玩意我也是自己在琢磨,然后资料也没有多少,简直就是自己慢慢摸索。
本期介绍如何利用TCP接收图片信息并显示。 欢迎大家加入交流群分享经验: ** 656210280 **
首先我们先新建一个类,将我们想要的内容全部写到这个类上(类的代码会放在最后面)

tcpListener用来创建监听,tcpClient用以发送。


public AndroidWifiService(){  
}~AndroidWifiService(){    tcpClient?.Close();    tcpClient = null;    tcpListener = null;    MessageReceived = null;}public AndroidWifiService(IPAddress address,int Port){    StartListening(address, Port);}  
public AndroidWifiService(string address, int Port){    StartListening(IPAddress.Parse(address), Port);}

提供三种类型的构造函数和析构函数。


protected virtual void OnMessageReceived(byte[] buffer){    // 触发事件    MessageReceived?.Invoke(this, buffer);}

设置一个事件,用以传递监听到的图片信息。


public async void StartListening(IPAddress IP,int Port){    tcpListener = new TcpListener(IP, Port);     tcpListener.Start();  
    while (true)    {        tcpClient = await tcpListener.AcceptTcpClientAsync();        Task.Run(() => HandleClient(tcpClient));    }}  
private void HandleClient(TcpClient client){    try    {        NetworkStream stream = client.GetStream();        byte[] buffer = new byte[1024]; // 使用固定大小的缓冲区        using (MemoryStream ms = new MemoryStream())        {            int bytesRead;            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)            {                ms.Write(buffer, 0, bytesRead);            }  
            if (ms.Length > 0)            {                // 在主线程上更新 UI                MainThread.BeginInvokeOnMainThread(() =>                {                    OnMessageReceived(ms.ToArray());                });            }        }    }    catch (Exception ex)    {        Console.WriteLine($"Exception in HandleClient: {ex.Message}");    }}

创建一个监听函数,注意的是, 我们是接受完一次完整的流再传递信息,而不是边接收边传递


private void OnMessageReceived(object sender, byte[] message){    MainThread.BeginInvokeOnMainThread(async () =>    {        try        {            using (MemoryStream ms = new MemoryStream(message))            {                SKBitmap bitmap = SKBitmap.Decode(ms);                AndroidSaveClass save = new AndroidSaveClass();                string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "MAUI_Picture_Save");                if (!save.DoesFolderExist(folderPath))                {                    Directory.CreateDirectory(folderPath);                }                // 生成文件路径                string uniqueFileName = $"sample_{DateTime.Now:yyyyMMddHHmmssfff}.png";                 string filePath = Path.Combine(folderPath, uniqueFileName);                // 将 SKBitmap 编码并保存为 PNG 文件                using (var image = SKImage.FromBitmap(bitmap))                using (var data = image.Encode(SKEncodedImageFormat.Png, 100))                using (var stream = File.OpenWrite(filePath))                {                    data.SaveTo(stream);                }  
                Picture.Source = filePath;  
            }        }        catch (Exception ex)        {            Console.WriteLine(ex.ToString());        }    });}  

再MainPage.xmal.cs中,我们新建一个这个类的变量,监听我们的窗口。并且设置回调函数用来处理事件。
事件中,我们将图片的字节数组转为图片,之后保存到程序的文件目录中,并且使用时间戳防止图片重复。
之后用Image控件来绑定图片源显示图片。

这样子图片就传递成功啦。


namespace MAUIapp.Platforms.Android.Servers{    public class AndroidWifiService : IWifiService    {        TcpListener? tcpListener;        TcpClient? tcpClient;  
        public event EventHandler<byte[]>? MessageReceived;  
        public AndroidWifiService()        {  
        }        ~AndroidWifiService()        {            tcpClient?.Close();            tcpClient = null;            tcpListener = null;            MessageReceived = null;        }        public AndroidWifiService(IPAddress address,int Port)        {            StartListening(address, Port);        }  
        public AndroidWifiService(string address, int Port)        {            StartListening(IPAddress.Parse(address), Port);        }  
        protected virtual void OnMessageReceived(byte[] buffer)        {            // 触发事件            MessageReceived?.Invoke(this, buffer);        }  
        public bool TCP_Send(string message,string IP ,int Port)        {            try            {                if (tcpClient == null || !tcpClient.Connected)                {                    // 创建并连接到服务器                    tcpClient = new TcpClient(IP,Port); // 请替换成你的服务器的IP地址                }  
                // 发送消息                using (NetworkStream stream = tcpClient.GetStream())                {                    byte[] buffer = Encoding.UTF8.GetBytes(message);                    stream.Write(buffer, 0, buffer.Length);                }  
                return true;            }            catch (Exception ex)            {                Console.WriteLine($"TCP_Send Exception: {ex.Message}");                return false;            }        }        public async void StartListening(IPAddress IP,int Port)        {            tcpListener = new TcpListener(IP, Port);             tcpListener.Start();  
            while (true)            {                tcpClient = await tcpListener.AcceptTcpClientAsync();                Task.Run(() => HandleClient(tcpClient));            }        }  
        private void HandleClient(TcpClient client)        {            try            {                NetworkStream stream = client.GetStream();                byte[] buffer = new byte[1024]; // 使用固定大小的缓冲区                using (MemoryStream ms = new MemoryStream())                {                    int bytesRead;                    while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)                    {                        ms.Write(buffer, 0, bytesRead);                    }  
                    if (ms.Length > 0)                    {                        // 在主线程上更新 UI                        MainThread.BeginInvokeOnMainThread(() =>                        {                            OnMessageReceived(ms.ToArray());                        });                    }                }            }            catch (Exception ex)            {                Console.WriteLine($"Exception in HandleClient: {ex.Message}");            }        }  
  
  
    }  
}  
1.转载请保留原文链接谢谢!
2.本站所有资源文章出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。
3.本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户擦亮眼睛自行鉴别,做一个有主见和判断力的用户。
4.本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
5.联系方式(#替换成@):pm#vimge.com

  相关内容