Unity中的简单套接字服务器 [英] Simple socket server in Unity

查看:96
本文介绍了Unity中的简单套接字服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Unity项目中使用C#插件.该插件应充当服务器,它将从客户端获取值,以便我可以将这些值用于进一步处理. 问题是服务器具有无限循环.无限循环会导致Unity挂起.该如何处理?

I want to use a C# plugin in my Unity project. That plugin should act as a server which will get values from a client so that I'd be able to use those values for further processing. The issue is that the server has infinite loop. And infinite loops cause Unity to hang. How to handle this?

我正在附上服务器程序的代码段.我认为有2点可能会引起问题.如代码中所述,无限循环和暂停程序的地方:

I'm attaching a code snippet of server program. In my opinion, there are 2 points which may be causing problem. The infinite loops and the point where program is suspended as commented in code:

void networkCode()
{
    // Data buffer for incoming data.
    byte[] bytes = new Byte[1024];

    // Establish the local endpoint for the socket.
    // Dns.GetHostName returns the name of the 
    // host running the application.
    IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
    IPAddress ipAddress = ipHostInfo.AddressList[0];
    IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 1755);

    // Create a TCP/IP socket.
    listener = new Socket(ipAddress.AddressFamily,
        SocketType.Stream, ProtocolType.Tcp);

    // Bind the socket to the local endpoint and 
    // listen for incoming connections.
    try
    {
        listener.Bind(localEndPoint);
        listener.Listen(10);

        // Start listening for connections.
        while (true)
        {
            // Program is suspended while waiting for an incoming connection.
            Debug.Log("HELLO");     //It works
            handler = listener.Accept();
            Debug.Log("HELLO");     //It doesn't work
            data = null;

            // An incoming connection needs to be processed.
            while (true)
            {
                bytes = new byte[1024];
                int bytesRec = handler.Receive(bytes);
                data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                if (data.IndexOf("<EOF>") > -1)
                {
                    break;
                }

                System.Threading.Thread.Sleep(1);
            }   

            System.Threading.Thread.Sleep(1);
        }
    }
    catch (Exception e)
    {
        Debug.Log(e.ToString());
    }
}

在@Programmer的帮助下,C#插件已完成.但是Unity无法读取正确的值.我要附加Unity侧代码:

After help from @Programmer, the C# plugin is complete. But Unity is not reading the correct values. I'm attaching the Unity side code:

using UnityEngine;
using System;

using SyncServerDLL;    //That's our library

public class receiver : MonoBehaviour {

    SynchronousSocketListener obj;   //That's object to call server methods

    // Use this for initialization
    void Start() {
        obj = new SynchronousSocketListener ();
        obj.startServer ();
    }

    // Update is called once per frame
    void Update() {
        Debug.Log (obj.data);
    }
}

我已经在Visual Studio中彻底测试了SynchronousSocketListener类.在那里效果很好.

I have tested SynchronousSocketListener class thoroughly in Visual Studio. It is giving good results there.

推荐答案

使用

Use Thread to do your server Listen and read and write actions. You can declare socket and other networkstream objects as public then initialize them in a thread function.

Unity在线程中的while循环中不能很好地工作,有时可能会冻结,但是您可以通过在while循环中添加System.Threading.Thread.Sleep(1);修复该问题.正在读取或等待数据从套接字到达.

Unity does not work well with while loops in Threads and may freeze sometimes, but you can fix that by adding System.Threading.Thread.Sleep(1); in your while loop where you are reading or waiting for data to arrive from socket.

确保停止OnDisable()功能中的线程.不要从新的Thread函数访问Unity API.只需在其中执行套接字操作,然后将数据返回到 public 变量即可.

Make sure to stop the Thread in OnDisable() function. Do NOT access Unity API from the new Thread function. Just do only the socket stuff there and return the data to a public variable.

System.Threading.Thread SocketThread;
volatile bool keepReading = false;

// Use this for initialization
void Start()
{
    Application.runInBackground = true;
    startServer();
}

void startServer()
{
    SocketThread = new System.Threading.Thread(networkCode);
    SocketThread.IsBackground = true;
    SocketThread.Start();
}



private string getIPAddress()
{
    IPHostEntry host;
    string localIP = "";
    host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (IPAddress ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            localIP = ip.ToString();
        }

    }
    return localIP;
}


Socket listener;
Socket handler;

void networkCode()
{
    string data;

    // Data buffer for incoming data.
    byte[] bytes = new Byte[1024];

    // host running the application.
    Debug.Log("Ip " + getIPAddress().ToString());
    IPAddress[] ipArray = Dns.GetHostAddresses(getIPAddress());
    IPEndPoint localEndPoint = new IPEndPoint(ipArray[0], 1755);

    // Create a TCP/IP socket.
    listener = new Socket(ipArray[0].AddressFamily,
        SocketType.Stream, ProtocolType.Tcp);

    // Bind the socket to the local endpoint and 
    // listen for incoming connections.

    try
    {
        listener.Bind(localEndPoint);
        listener.Listen(10);

        // Start listening for connections.
        while (true)
        {
            keepReading = true;

            // Program is suspended while waiting for an incoming connection.
            Debug.Log("Waiting for Connection");     //It works

            handler = listener.Accept();
            Debug.Log("Client Connected");     //It doesn't work
            data = null;

            // An incoming connection needs to be processed.
            while (keepReading)
            {
                bytes = new byte[1024];
                int bytesRec = handler.Receive(bytes);
                Debug.Log("Received from Server");

                if (bytesRec <= 0)
                {
                    keepReading = false;
                    handler.Disconnect(true);
                    break;
                }

                data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                if (data.IndexOf("<EOF>") > -1)
                {
                    break;
                }

                System.Threading.Thread.Sleep(1);
            }

            System.Threading.Thread.Sleep(1);
        }
    }
    catch (Exception e)
    {
        Debug.Log(e.ToString());
    }
}

void stopServer()
{
    keepReading = false;

    //stop thread
    if (SocketThread != null)
    {
        SocketThread.Abort();
    }

    if (handler != null && handler.Connected)
    {
        handler.Disconnect(false);
        Debug.Log("Disconnected!");
    }
}

void OnDisable()
{
    stopServer();
}

这篇关于Unity中的简单套接字服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆