今天有点闲,有点闲,有点闲...然后我用一个小时做了一个小功能:用一个电脑A控制另一台电脑B中两个正在运行的程序在屏幕上的显示顺序,也就是点击电脑A中的按钮C,将电脑B中的程序C显示在屏幕最前方;点击电脑A中的按钮D,将电脑B中的程序D显示在屏幕最前方,如下图所示(上传图片限制大小,将就着看吧)【电脑A可以替换成手机,充当一个遥控的作用】
用到的功能:
- 局域网服务器、客户端通信;也可见文章TcpListener与TcpClient
- 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();
}
}