【问题标题】:C# Socket stops receivingC# Socket 停止接收
【发布时间】:2018-12-07 22:23:03
【问题描述】:

我正在 C# 中为我的 Unity 应用程序创建一个服务器套接字。我从下面的链接创建了异步服务器套接字 Asynchronous Server Socket

使用它我可以成功地与客户端连接并从客户端接收数据。但是在收到少量数据后,即使客户端正在发送数据,套接字也没有接收到数据(我正在同一台机器上测试客户端和服务器)。

try catch 也没有抛出异常。所以我无法确定根本原因。

请在下面找到我的代码

public class NetworkStateObject
{
        // Client socket.  
        public Socket workSocket = null;
        // Size of receive buffer.  
        public const int BufferSize = 1024;
        // Receive buffer.  
        public byte[] buffer = new byte[BufferSize];
        // Received data string.  
        public List<byte> receivedBytes = new List<byte>();
}

private readonly ManualResetEvent allDone = new ManualResetEvent(false);
private readonly ManualResetEvent receiveDone = new ManualResetEvent(false);
private readonly string receiveDelimitter = "<EOF>";

socketThread = new Thread(new ThreadStart(StartSocketServer));
socketThread.Priority = System.Threading.ThreadPriority.BelowNormal;
socketThread.IsBackground = true;
socketThread.Start();

protected void Receive(Socket socket)
{
        ReceiveData(socket);
        receiveDone.WaitOne();
}

private void ReceiveData(Socket socket)
    {
        try
        {
            // Create the state object.  
            NetworkStateObject state = new NetworkStateObject();
            state.workSocket = socket;

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

private void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        // Retrieve the state object and the client socket   
        // from the asynchronous state object.  
        NetworkStateObject state = (NetworkStateObject)ar.AsyncState;
        Socket socket = state.workSocket;

        // Read data from the remote device.  
        int bytesRead = socket.EndReceive(ar);

        if (bytesRead > 0)
        {
            // There might be more data, so store the data received so far.  
            //state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
            var bytesArray = state.buffer;
            if (bytesRead < NetworkStateObject.BufferSize)
            {
                Array.Resize(ref bytesArray, bytesRead);
            }
            var bytesList = new List<byte>(bytesArray);
            state.receivedBytes.AddRange(bytesList);

            var receivedBytes = state.receivedBytes;
            var bytesCount = receivedBytes.Count;
            if (receivedBytes.Count > 1)
            {
                var receivedString = Encoding.ASCII.GetString(receivedBytes.ToArray(), 0, bytesCount);
                if (receivedString.IndexOf(receiveDelimitter, StringComparison.CurrentCulture) > -1)
                {
                    var message = receivedString.Replace(receiveDelimitter, String.Empty);
                    message = Regex.Unescape(message);
                    socketBaseDelegate.ReceivedMessage(message);
                    state.receivedBytes.Clear();
                    receiveDone.Set();
                }
                else
                {
                    // Get the rest of the data.
                    socket.BeginReceive(state.buffer, 0, NetworkStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                }
            }
        }
        else
        {
            receiveDone.Set();
        }
    }
    catch (Exception e)
    {
        Debug.Log(e.ToString());
    }
}

public void ReceivedMessage(string data)
    {
        socketInputParser.Parse(data);
        asynchronousSocketListener.ReceiveMessage();
    }

在上面的代码中,ReceiveCallback 在一段时间后没有被触发。 即使客户端发送数据。

【问题讨论】:

    标签: c# sockets unity3d


    【解决方案1】:
    else
    {
      // Get the rest of the data.
      socket.BeginReceive(state.buffer, 0, NetworkStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
    }
    

    这部分不应该是有条件的。一旦接收回调完成,您应该始终重新开始接收。当然,除非连接被终止。

    【讨论】:

    • 我确实通过调用 Receive(Socket socket) 函数从我的控制器启动它。而且我确实收到了很多次字节,但过了一段时间,即使我调用了 Receive 函数,也没有在某个时间后调用 ReceiveCallback 函数。
    • 该方法应该在 try 范围内的 catch 之前。我的假设是您有时会退出而没有再次收到。
    • 我相信你的意思是 socket.BeginReceive 调用,如果你看一下 ReceivedMessage 函数,我会再次调用 ReceiveMessage 内部调用 Receive(Socket socket) 函数,所以它会一直监听直到控制器决定停下来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2011-05-30
    相关资源
    最近更新 更多