如何在C#

时间:2015-11-20 14:17:53

标签: c# sockets tcp

我一直在使用c#中的TCP套接字在客户端/服务器应用程序中消耗慢客户端消息。每当慢客户端连接到服务器时,它都会影响其他客户端的处理。

在c#中阅读了一些关于tcp / ip堆栈的文献后,我得出结论,由于客户端RCV_BUFFER已满,服务器端SND_BUFFER已满,其他客户端正在影响。

虽然我无法在真实环境中制作场景,所以这就是我为模拟慢速客户端消息处理所做的工作。

  1. 为客户端创建了示例应用程序,并在从RCV_BUFFER读取之前实现了1到10秒的休眠(因此它可以是满的)。
  2. 连接两个客户端(一个具有不同的睡眠时间而另一个没有睡眠时间)。
  3. 我看到那个没有睡眠时间的客户正在影响,但我无法确定这个问题的模式。

    以下是一些疑问,我想清除我的困惑。  1.如何在将数据发送到服务器端的TCP SEND_WINDOW之前确定SND_BUFFER的大小。  2.我应该采取哪些步骤来确定问题的模式。所以我可以继续解决。

    以下是服务器端的代码段。

    public bool Start()
    {
        try
        {
            _listener.Bind(new IPEndPoint(IPAddress.Any, _port));
            _listener.Listen(2000);
            _listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 5000);
            _listener.BeginAccept(ConnectionReady, null);
            LogHelper.ErrorLogger.Debug("Listening started");
            return true;
        }
        catch
        {
            return false;
        }
    }
    
    public void createSession(object obj)
    {
        Socket conn = (Socket)obj;
        try
        {
            LogHelper.ErrorLogger.Debug("Creating Session");
            ConnectionState st = new ConnectionState(conn); // Custom class for maintaining the socket object
            st._server = this;
            st._provider = _provider;
            st._buffer = new byte[4];
            st._provider.OnAcceptConnection(st);
            AcceptConnection.BeginInvoke(st, null, st);
            LogHelper.ErrorLogger.Debug("Session Created");
        }
        catch (Exception ex)
        {
            try
            {
                conn.Close();
            }
            catch { }
            LogHelper.ErrorLogger.Debug("Session aborted -          >" + ex.ToString());
        }
    }
    
    private void AcceptConnection_Handler(object state)
    {
        try
        {
            ConnectionState st = state as ConnectionState;
            try
            {
                st.AuthenticateSocket();
    
                //Starts the ReceiveData callback loop
                if (st._conn.Connected)
                    st._conn.BeginReceive(st._buffer, 0, 0, SocketFlags.None, ReceivedDataReady, st);
            }
            catch
            {
                DropConnection(st);
            }
        }
        catch { }
    }
    
    private void ReceivedDataReady_Handler(IAsyncResult ar)
    {
        try
        {
            ConnectionState st = ar.AsyncState as ConnectionState;
            try
            {
                try
                {
                    int bytesRcv = st._conn.EndReceive(ar);
                    //Encoding.UTF8.GetString(buffer, 0, readBytes);
                    //state.msgBuffer.Append(_receivedStr);
                }
                catch
                {
                    DropConnection(st); return;
                }
                //Im considering the following condition as a signal that the
                //remote host droped the connection.
                if (st._conn.Available == 0)
                {
                    DropConnection(st);//@@SHARIQ
                    return;
                }
                else
                {
                    try
                    {
                        st._provider.OnReceiveData(st);
                    }
                    catch
                    {
                        return;
                    }
                    //Resume ReceivedData callback loop
                    if (st._conn.Connected)
                        st._conn.BeginReceive(st._buffer, 0, 0, SocketFlags.None, ReceivedDataReady, st);
                }
            }
            catch { DropConnection(st); return; }
        }
        catch { }
    }
    

    从MSMQ获取消息(一个线程正在运行以通过接收器对象从MSMQ获取消息),并且在触发事件后提取消息并从消息中提取IP地址并将一条消息发送到套接字。

    private void m_broker_OnMessage(object obj)
    {
        try
        {
            Message m = (Message)obj;
            m.Formatter = new BinaryMessageFormatter();
            ConnectionState tstate = null;
            bool containststate = false;
            string TempLabels = string.Empty;
            string BodyMessage = string.Empty;
            if (m.Body.ToString().StartsWith("="))
            {
                BodyMessage = (string)m.Body;
                TempLabels = BodyMessage.Substring(1, BodyMessage.IndexOf('#') - 1);
                BodyMessage = BodyMessage.Substring(BodyMessage.IndexOf('#') + 1);
            }
            if (!string.IsNullOrEmpty(TempLabels))
            {
                string[] labels = TempLabels.Split(',');
                foreach (string label in labels)
                {
                    lock (cons)
                    {
                        containststate = cons.Contains(label);
                        if (containststate)
                        {
                            tstate = (ConnectionState)cons[label];
                        }
    
                    }
                    if (containststate)
                    {
                        ConnectionState state = tstate;
                        if (!state.WriteLine(BodyMessage + "1057=" + label + "#"))
                        {
                            OnDropConnection(state);
                            continue;
                        }
                        if (ConfigurationSettings.AppSettings["FullLog"] == "1")
                        {
                            eventLogger.Debug("OUT " + label + " " + BodyMessage);
                        }
                    }
                    else
                    {
                        long result;
                        if (!lastResolve.Contains(label))
                        {
                            if ((!string.IsNullOrEmpty(label)) && long.TryParse(label, out result))
                            {
                                if (ConfigurationSettings.AppSettings["FullLog"] == "1")
                                {
                                    eventLogger.Info("Label not found: " + label);
                                }
                                string msg = "8=EXX.1.0#35=C7#1057=" + label + "#";
                                this.Send(msg, label, "0.0.0.0");
                                eventLogger.Info("Connection Disconnected: " + label);
                                //Nothing to clean here
                                lock (cons)
                                {
                                    if (cons.Contains(label))
                                    {
                                        try
                                        {
                                            string ipaddress = ((ConnectionState)cons[label]).RemoteEndPoint.ToString().Split(':')[0];
                                            connectionGroups[ipaddress]--;
                                        }
                                        catch { }
                                    }
                                    cons.Remove(label);
                                    lastResolve.Add(label);
                                }
                            }
                        }
                        continue;
                    }
                }
            }
            else
            {
                lock (cons)
                {
                    containststate = cons.Contains(m.Label);
                    if (containststate)
                    {
                        tstate = (ConnectionState)cons[m.Label];
                    }
    
                }
                if (containststate)
                {
                    ConnectionState state = tstate;
                    if (!state.WriteLine((string)m.Body + "1057=" + m.Label + "#"))
                    {
                        OnDropConnection(state);
                        return;
                    }
                    if (ConfigurationSettings.AppSettings["FullLog"] == "1")
                    {
                        eventLogger.Debug("OUT " + m.Label + " " + m.Body.ToString());
                    }
                }
                else
                {
                    long result;
                    if (!lastResolve.Contains(m.Label))
                    {
                        if ((!string.IsNullOrEmpty(m.Label)) && long.TryParse(m.Label, out result))
                        {
                            if (ConfigurationSettings.AppSettings["FullLog"] == "1")
                            {
                                eventLogger.Info("Label not found: " + m.Label);
                            }
                            string msg = "8=EXX.1.0#35=C7#1057=" + m.Label + "#";
                            this.Send(msg, m.Label, "0.0.0.0");
                            eventLogger.Info("Connection Disconnected: " + m.Label);
                            //Nothing to clean here
                            lock (cons)
                            {
                                if (cons.Contains(m.Label))
                                {
                                    try
                                    {
                                        string ipaddress = ((ConnectionState)cons[m.Label]).RemoteEndPoint.ToString().Split(':')[0];
                                        connectionGroups[ipaddress]--;
                                    }
                                    catch { }
                                }
                                cons.Remove(m.Label);
                                lastResolve.Add(m.Label);
                            }
                        }
                    }
                    return;
                }
            }
        }
        catch (Exception e)
        {
            errorLogger.Error(e.Message, e);
        }
    }
    

    以阻止方式发送

    public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags)
    {
        lock (sendObject)
        {
            try
            {
                if (_innerSocketStream.IsUsingSsl)
                {
    
                    myStream.Write(buffer, offset, size);
                }
                else
                {
                    _innerSocketStream.Socket.Send(buffer, offset, size, SocketFlags.None);
                }
            }
            catch (SocketException)
            {
                return 0;
            }
            return size;
        }
    }
    

0 个答案:

没有答案