【问题标题】:C# Socket connection can't receive more than onceC# Socket 连接不能多次接收
【发布时间】:2023-04-04 12:41:01
【问题描述】:

我有一个用 C 语言向统一发送消息的服务器。在 Unity 中,我可以接收一次数据,但是当服务器发送新消息时,Unity 什么也没有收到。

例如:Unity 可以连接到服务器,接收到第一条说“向右移动”的消息,然后将 Unity 的相机向右移动,但是如果服务器发送“向左移动”或其他任何东西,统一在功能中被阻止接收哪些调用 BeginReceive:

client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);

我的服务器代码:

void connectToUnity() {
    SOCKADDR_IN sin;
    WSAStartup(MAKEWORD(2, 0), &WSAData);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    sin.sin_family = AF_INET;
    sin.sin_port = htons(53660);
    bind(sock, (SOCKADDR*)&sin, sizeof(sin));
    listen(sock, 0);
    printf("Connexion to unity\n");
}

void sendDataToUnity(const char * mouvement) {
    SOCKET csock;
    while (1)
    {
        int sinsize = sizeof(csin);
        if ((csock = accept(sock, (SOCKADDR*)&csin, &sinsize)) != INVALID_SOCKET)
        {
            send(csock, mouvement, 14, 0);
            printf("Donnees envoyees \n");
            return;
        }
        else {
            printf("Rien n'a ete envoye");
        }
    }
}

Unity 中的代码:

public bool ConnectToServer(string hostAdd, int port)
    {  
        //connect the socket to the server
        try
        {
            //create end point to connect
            conn = new IPEndPoint(IPAddress.Parse(hostAdd), port);
            //connect to server

                      
            clientSocket.BeginConnect(conn, new AsyncCallback(ConnectCallback), clientSocket);
            socketReady = true;

            connectDone.WaitOne();

            Debug.Log("Client socket ready: " + socketReady);


            // Receive the response from the remote device.  
            Receive(clientSocket);
            //receiveDone.WaitOne();

        


        }
        catch (Exception ex)
        {
            Debug.Log("socket error: " + ex.Message);
        }

        return socketReady;
    }

    //async call to connect
    static void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket 
            Socket client = (Socket)ar.AsyncState;

            // Complete the connection  
            client.EndConnect(ar);

            Debug.Log("Client Socket connected to: " + client.RemoteEndPoint);

           connectDone.Set();

        }
        catch (Exception e)
        {
            Debug.Log("Error connecting: " + e);
        }
    }

    private static void Receive(Socket client)
    {
        try
        {
            Debug.Log("Try to receive");
            // Create the state object.  
            StateObject state = new StateObject();
            state.workSocket = client;


            // Begin receiving the data from the remote device.  
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        catch (Exception e)
        {
            Debug.Log(e);
        }
    }

    static void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            //Read data from the remote device.  
            Debug.Log("receive callback");
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;

            int bytesRead = client.EndReceive(ar);

            if (bytesRead > 0)
            {
                Debug.Log("Il y a une réponse");
                
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
                
                
                response = state.sb.ToString();
                Debug.Log(response);

                

                //client.Shutdown(SocketShutdown.Both);
            }
            else
            {

                if(state.sb.Length > 1)
                {
                    response = state.sb.ToString();
                    Debug.Log(response);
                }
            }
           
        }
        catch (Exception ex)
        {
            Debug.Log("Error: " + ex.Message);
        }
    }

函数接收在函数ConnectToServer中被调用一次,然后我尝试在更新中再次调用,如下所示:

  void Update()
    {
        if (response.Contains("right"))
        {
            Debug.Log("Move to the right ");
            float x = Camera.main.transform.localEulerAngles.x;
            float y = Camera.main.transform.localEulerAngles.y;

            DeplacementCamera.moveRight(x, y);
            response = "";

            Receive(clientSocket);
            
        }
    }

我已经看过这篇文章但没有成功,或者我尝试了错误的方式:

Why does BeginReceive() not return for more than one read?

编辑:在函数 ReceiveCallback 中永远不会到达 else。

【问题讨论】:

  • 您能否展示您的Receive 方法以及重现此操作所需的所有信息?

标签: c# c sockets unity3d client-server


【解决方案1】:

你可以改变你的方法

  private void SetupReceiveCallback(Socket sock)
    {
        try
        {
            DataBuffer = new byte[BufferSize];
            AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
            sock.BeginReceive(DataBuffer, 0, DataBuffer.Length, SocketFlags.None, recieveData, _socket);
        }
        catch (Exception E)
        {
           
        }
    }
 private void OnRecievedData(IAsyncResult ar)
    {
        Socket sock = (Socket)ar.AsyncState;

        try
        {
            if (sock.Connected)
            {
                int nBytesRec = sock.EndReceive(ar);

                if (nBytesRec > 0)
                {

                    string Data = Encoding.UTF8.GetString(DataBuffer);
                    if (Data.Length != 4)
                    {
                        string JsonString = Data;
                        if (!string.IsNullOrEmpty(JsonString))
                        {
                            
                            try
                            {
                               //Add you code processing here
                            }
                            catch (Exception ex)
                            {
                                
                            }
                        }
                        BufferSize = 4;
                    }
                    else
                    {
                        BufferSize = BitConverter.ToInt32(DataBuffer, 0);
                    }
                }


                SetupReceiveCallback(sock);
            }
            else
               // on not connected to socket
        }
        catch (Exception E)
        {
            
        }
    }

public bool Connect(string IP, int Port)
    {
        try
        {
           _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //if (IsValidIP(IP))
            //{
          
            //    IPEndPoint epServer = new IPEndPoint(IPAddress.Parse(IP), Port);
            //    _socket.Connect(epServer);
            //}
            //else
            //{
         
            //    _socket.Connect(IP, Port);
            //}

            //SetupReceiveCallback(_socket);


            
        }
        catch(Exception ex)
        {

        }
        return false;
    }

【讨论】:

    猜你喜欢
    • 2014-09-23
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    • 2014-02-26
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    相关资源
    最近更新 更多