Unity|用一个PC端控制另一个PC端上两个程序的屏幕显示顺序

今天有点闲,有点闲,有点闲...然后我用一个小时做了一个小功能:用一个电脑A控制另一台电脑B中两个正在运行的程序在屏幕上的显示顺序,也就是点击电脑A中的按钮C,将电脑B中的程序C显示在屏幕最前方;点击电脑A中的按钮D,将电脑B中的程序D显示在屏幕最前方,如下图所示(上传图片限制大小,将就着看吧)【电脑A可以替换成手机,充当一个遥控的作用】

用到的功能:

  1. 局域网服务器、客户端通信;也可见文章TcpListener与TcpClient
  2. Windows用户界面相关应用程序接口的运用;

代码如下:

  • 服务器端
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System.Net;
using System.Text;
using UnityEngine.UI;
using System.Threading;

public class Server : MonoBehaviour
{
    public static Server _instance;
    private TcpListener tcpListener;
    private TcpClient client1;
    private TcpClient client2;
    private string ip = "10.1.12.21";//本地ip
    private int port = 9001;
    private ClientSocket clientSocket1;
    private ClientSocket clientSocket2;
    private Button buttonA;
    private Button buttonB;
    public bool clientA = false;
    public bool clientB = false;

    private void Awake()
    {
        _instance = this;
        buttonA = transform.Find("buttonA").GetComponent<Button>();
        buttonA.onClick.AddListener(delegate
        {
            clientA = true;
        });
        buttonB = transform.Find("buttonB").GetComponent<Button>();
        buttonB.onClick.AddListener(delegate
        {
            clientB = true;
        });
    }
    private void Start()
    {
        Thread thread = new Thread(new ThreadStart(startThread));
        thread.Start();
    }
    void startThread()
    {
        tcpListener = new TcpListener(IPAddress.Parse(ip), port);
        tcpListener.Start();
        //两个客户端
        client1 = tcpListener.AcceptTcpClient();
        clientSocket1 = new ClientSocket(client1);
        client2 = tcpListener.AcceptTcpClient();
        clientSocket2 = new ClientSocket(client2);
    }
   
    private void OnDestroy()
    {
        if (tcpListener != null)
            tcpListener.Stop();
        if (clientSocket1 != null)
            clientSocket1.ClientClose();
        if (clientSocket2 != null)
            clientSocket2.ClientClose();
    }

    public class ClientSocket {
        private TcpClient _client;
        private NetworkStream stream;
        private Thread clientThread;
        byte[] bytesRead = new byte[1024];
        bool _connected;
        byte[] bytesSend;

        public ClientSocket(TcpClient client)
        {
            _client = client;
            stream = _client.GetStream();
            clientThread = new Thread(new ThreadStart(StartClient));
            clientThread.IsBackground = true;
            clientThread.Start();
        }
        bool IsOpen()
        {
            return !((_client.Client.Poll(1000, SelectMode.SelectRead)
                && (_client.Client.Available == 0)) || !_client.Client.Connected);
        }
        void StartClient()
        {
            while (true)
            {
                _connected = IsOpen();
                if (_connected &&_instance.clientA)//点击按钮A,发送OnClickA               
                {
                    bytesSend = Encoding.UTF8.GetBytes("OnClickA");
                    stream.Write(bytesSend, 0, bytesSend.Length);
                    _instance.clientA = false;
                }
                if(_connected && _instance.clientB)//点击按钮B,发送OnClickB  
                {
                    bytesSend = Encoding.UTF8.GetBytes("OnClickB");
                    stream.Write(bytesSend, 0, bytesSend.Length);
                    _instance.clientB = false;
                }
                if (stream.DataAvailable && _connected)//接收客户端数据
                {
                    int length = stream.Read(bytesRead, 0, 1024);
                    if (length > 0)
                    {
                        string getMsg = Encoding.UTF8.GetString(bytesRead, 0, length);
                        Debug.Log(getMsg);
                    }
                }
            }
        }
        public void ClientClose()
        {
            stream.Close();
            _client.Close();
        }
    }
}
  • 客户端A:(客户端B类似)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;

public class ClientA : MonoBehaviour {
    [DllImport("User32.dll")]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();

    [DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("User32.dll")]
    private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

    private TcpClient client;
    private NetworkStream stream;
    byte[] bytesWrite;
    byte[] bytesRead = new byte[1024];
    private bool __connected;
    private Text text;
    private string ip = "10.1.12.21";//服务器端ip
    private string exeName = "ClientA";
    private void Awake()
    {
        text = transform.Find("text").GetComponent<Text>();
    }

    void Start()
    {
        text.text = "这是客户端A";
        Thread thread = new Thread(new ThreadStart(StartThread));
        thread.Start();
    }
    //socket连接是否有效
    bool IsOpen()
    {
        return !((client.Client.Poll(1000, SelectMode.SelectRead) &&
            (client.Client.Available == 0)) || !client.Client.Connected);
    }
    void StartThread()
    {
        bool hasWrite = false;
        while (true)
        {
            if (!__connected)
            {
                TryConnect();
            }
            if (__connected && !hasWrite)  //发送一次                       
            {
                bytesWrite = Encoding.UTF8.GetBytes("客户端A已经启动~\n");
                stream.Write(bytesWrite, 0, bytesWrite.Length);
                hasWrite = true;
            }
            if (stream.DataAvailable && __connected)
            {
                int length = stream.Read(bytesRead, 0, 1024);
                if (length > 0)
                {
                    string getMsg = Encoding.UTF8.GetString(bytesRead, 0, length);
               
                    if (getMsg == "OnClickA")//如果接收到OnClickA数据,则把该运行程序设置为活动窗口
                    {
                        IntPtr hwnd = FindWindow(null, exeName);

                        // 如果没有找到,则不做任何操作(找不到一般就是apptitle错了)
                        if (hwnd == IntPtr.Zero)
                        {
                            return;
                        }
                        IntPtr activeWndHwnd = GetForegroundWindow();

                        // 当前程序不是活动窗口,则设置为活动窗口
                        if (hwnd != activeWndHwnd)
                        {
                            ShowWindowAsync(hwnd, 3);
                            SetForegroundWindow(hwnd);
                        }
                    }
                }
            }
        }
    }
    private void TryConnect()
    {
        try
        {
            client = new TcpClient();
            IAsyncResult result = client.BeginConnect(IPAddress.Parse(ip), 9001, null, null);
            __connected = result.AsyncWaitHandle.WaitOne(1000, false);
            if (__connected)
            {
                text.text = "我是A 已连接到服务器:\n";
                client.EndConnect(result);
            }
            else
            {
                Debug.Log("连接失败!");
                client.Close();
            }
        }
        catch (SocketException e)
        {
            __connected = false;
            Debug.Log("警告:连接出现异常--> " + e.Message);
            client.Close();
            return;
        }
        if (__connected)
        {
            stream = client.GetStream();
        }
    }
    private void OnDestroy()
    {
        if (stream != null) stream.Close();
        if (client != null) client.Close();
    }
}
发布了162 篇原创文章 · 获赞 20 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_39766005/article/details/100104519