Unity中的简单套接字服务器

时间:2016-04-10 05:50:07

标签: c# sockets unity3d

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

编辑:我附上了服务器程序的代码段。在我看来,有两点可能导致问题。无限循环和程序暂停的点,如代码所示:

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端代码:

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类。它在那里给出了很好的结果。

1 个答案:

答案 0 :(得分:6)

使用Thread执行服务器侦听和读写操作。 您可以将socket和其他网络流对象声明为public,然后在线程函数中初始化它们。

Unity在线程中的while循环效果不佳,有时可能冻结,但您可以通过在while中添加OnDisable()修复你正在读取或等待数据从套接字到达的循环。

确保在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(); } 功能中停止线程。 NOT 从新的Thread函数访问Unity API。只需在那里填充套接字并将数据返回到 public 变量。

df.loc[pd.isnull(df.col5),'col5']= np.arange(3)