除非我设置断点,否则C#套接字会丢失一些数据

时间:2013-12-04 16:23:00

标签: c# sockets

我正在解决一个相对简单的套接字应用程序的问题,该应用程序正在侦听来自第三方机器的状态更新。我已经设置了一个TcpListener对象来等待连接请求,然后建立套接字来读取进来的数据。我得到了预期的心跳,没有问题,但是只要状态突然发生变化,服务器就会发出一个立即更新我不明白。这里奇怪的是,如果我在代码中设置了一个断点,我的更新没问题。

服务器本身处理这些连接有点奇怪,并且没有保持打开的套接字连接。当它试图发送数据时,它会打开连接,发送数据,然后关闭连接,这就是为什么我构建它同样等待连接并在数据传输完成之前关闭它然后再开始监听另一个连接请求。

private void ListeningThread()
    {
        bool keep_going = CreateConnection();

        CreateTimer();

        while (keep_going)
        {
            try
            {
                if (m_ThreadShutdownEvent.IsSet)
                {
                    // event was set, so shut down
                    keep_going = false;
                    m_Listener.Stop();

                    bool appshuttingdown = false;

                    DestroyTimer();

                    lock (m_Lock)
                    {
                        appshuttingdown = m_ApplicationShutDown;
                    }

                    if (!appshuttingdown)
                    {
                        RunStatusNotification();
                    }

                    Connected = false;
                }
                else
                {
                    if (m_Listener.Pending())
                    {
                        Socket socket = m_Listener.AcceptSocket();

                        if (socket != null)
                        {
                            StateObject state = new StateObject();
                            state.Socket = socket;

                            try
                            {
                                int bytes_read = socket.Receive(state.Buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None);
                                DateTime now = DateTime.UtcNow;
                                if (bytes_read == 14)
                                {
                                    if (state.Buffer.Count() > 13)
                                    {
                                        int packet = state.Buffer[13];
                                        InterpretRelevantByte(packet, now);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                FireUnknownException(ex);
                            }
                            finally
                            {
                                socket.Close();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                m_Logger.Error(ex);
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

您的接收调用可能会使您获得大于或小于14的值,您可能应该添加一些逻辑来检查当读取的字节数不等于14时您收到的数据,因为在这些情况下您丢弃了什么已经读过了。

int bytes_read = socket.Receive(state.Buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None);
DateTime now = DateTime.UtcNow;

if (bytes_read == 14)
{
    if (state.Buffer.Count() > 13)
    {
        int packet = state.Buffer[13];
        InterpretRelevantByte(packet, now);
    }
}
else if (bytes_read > 14)
{
    // maybe you received multiple messages in one packet
}
else
{
    // maybe there is more data on the way
}

答案 1 :(得分:0)

好的,我已经解决了这个问题。事实证明我过早关闭套接字会导致一些奇怪的行为,说实话,我并不完全理解,但我确实知道如何修复它。

打开套接字后,我需要继续侦听数据,直到收到0长度消息,表示服务器已关闭连接。此时我可以开始侦听新的套接字连接请求。我仍然不确定为什么我只会获得心跳,但是自从我做出改变以来,一切都很完美。