【问题标题】:Unity TCP Server Hang Unity sceneUnity TCP Server Hang Unity场景
【发布时间】:2012-12-07 14:05:36
【问题描述】:

我正在尝试统一实现 TCP 服务器。我正在使用unity pro 3.5,当我在场景中运行此代码时,统一挂起,完全没有响应,直到我用任务管理器将其杀死。

using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.Net;
using System.Text;


public class Server : MonoBehaviour {

    private IPAddress ipAd;
    public string IP="127.0.0.1";
    public int port = 8001;
    private Socket s;

    void Update ()
    {   

    }

    // Use this for initialization
    void Awake () {
            port = 8001;
            ipAd = IPAddress.Parse(IP);
            msg = "Listening at " + IP + ":" + port.ToString();
            this.s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            this.s.Bind(new IPEndPoint(ipAd,port));
            this.s.Listen(200);
            while (true)
              this.ReceiveMessage(this.s.Accept()); //hang if this line activated
    }
    private void ReceiveMessage(Socket socket)
        {
            byte[] tempbuffer = new byte[10000];
            socket.Receive(tempbuffer);
            rec.AssignFromByteArray(tempbuffer);                
        }
}

【问题讨论】:

    标签: unity3d crash tcplistener


    【解决方案1】:

    服务器应该在它自己的线程中运行,这样即使tcp_Listener.AcceptSocket() 是阻塞调用,GameLoop 也可以继续。

    using UnityEngine;
    using System.Collections;
    using System.Threading;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    
    public class Server : MonoBehaviour {
        private bool mRunning;
        public static string msg = "";
    
        public Thread mThread;
        public TcpListener tcp_Listener = null;
    
        void Awake() {
            mRunning = true;
            ThreadStart ts = new ThreadStart(Receive);
            mThread = new Thread(ts);
            mThread.Start();
            print("Thread done...");
        }
    
        public void stopListening() {
            mRunning = false;
        }
    
        void Receive() {
            tcp_Listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8001);
            tcp_Listener.Start();
            print("Server Start");
            while (mRunning)
            {
                // check if new connections are pending, if not, be nice and sleep 100ms
                if (!tcp_Listener.Pending()){
                    Thread.Sleep(100);
                }
                else {
                    Socket ss = tcp_Listener.AcceptSocket();
                    BonePos rec = new BonePos();
                    byte[] tempbuffer = new byte[10000];
                    ss.Receive(tempbuffer); // received byte array from client
                    rec.AssignFromByteArray(tempbuffer); // my own datatype
                }
            }
        }
    
        void Update() {
    
        }
    
        void OnApplicationQuit() { // stop listening thread
            stopListening();// wait for listening thread to terminate (max. 500ms)
            mThread.Join(500);
        }
    }
    

    Related answer from answers.unity3d.com

    【讨论】:

    • mRunning 应该是易变的。该变量由Unity线程设置,从接收线程读取,所以访问应该是同步的。
    【解决方案2】:

    你因此而被绞死:

    while (true)
              this.ReceiveMessage(this.s.Accept()); //hang if this line activated
    

    整个过程卡在这个循环中,所以没有其他处理。

    您可以做的(尽管我不推荐)是在 update() 中执行操作,而不是无限循环。

    我的建议是使用其他东西来运行您的服务器而不是统一。

    如果您正在创建游戏服务器,您可以使用 PUN(Photon Unity Networking)或使用 C# 编写独立服务器,甚至可以使用 Python 编写符合您需求的开源服务器。

    【讨论】:

      【解决方案3】:

      你必须摆脱这种说法:

      while (true)
          this.ReceiveMessage(this.s.Accept());
      

      而且你的服务器必须在他自己的线程中运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多