【Windows-C#】TCP Connect refused

49 Views Asked by At

everyone. I had written one TCP server program in C# as following, after running it and using jmeter to test it with 1000 threads in 1 second(In such condition, I type the backlog size as 10000). there are about 800 connection ready but others fail with "connection refused.", Could anyone give me some advices?

`

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Socket listenSocket;
        private static ArrayList g_fdlist = new ArrayList();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void btn_confirm_Click(object sender, RoutedEventArgs e)
        {
            var port = Convert.ToInt32(tb_port.Text);
            var backlog = Convert.ToInt32(backlogSize.Text);
            start_socket_server(port, backlog);
            //start_socket_server_selectmode(port, backlog);
        }
        #region select
        private void start_socket_server_selectmode(int port, int backlog)
        {
            if (listenSocket != null)
            {
                listenSocket.Close();
                listenSocket = null;
            }

            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);
            listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            listenSocket.Bind(localEndPoint);
            listenSocket.Listen(backlog);
            System.Console.WriteLine(fetchcurrentTime() + ": Start Listen in " + port + ", " + backlog);

            Thread t = new Thread(new ThreadStart(workThread));
            t.Start();

            while (true)
            {
                Socket s = listenSocket.Accept();
                System.Console.WriteLine(fetchcurrentTime() + ": Accept connect " + s.RemoteEndPoint.ToString());
                g_fdlist.Add(s);
            }
        }
        private void workThread()
        {
            ArrayList selectFDlist = new ArrayList();
            while (true)
            {
                selectFDlist.Clear();
                for (int i=0; i<g_fdlist.Count; ++i)
                {
                    selectFDlist.Add(g_fdlist[i]);
                }
                if (selectFDlist.Count <= 0)
                {
                    continue;
                }

                Socket.Select(selectFDlist, null, null, 1);
                int num = selectFDlist.Count;
                byte[] buf = new byte[100];
                foreach(Socket s in selectFDlist)
                {
                    int retlen = s.Receive(buf);
                    if(retlen > 0)
                    {
                        System.Console.WriteLine(fetchcurrentTime() + ": Receive data from " + s.RemoteEndPoint.ToString());
                        
                        Thread.Sleep(10000);
                    } else
                    {
                        System.Console.WriteLine(fetchcurrentTime() + ": socket is closed. " + s.RemoteEndPoint.ToString());
                        s.Shutdown(SocketShutdown.Both);
                        s.Close();
                        g_fdlist.Remove(s);
                    }
                }
            }
        }
        #endregion select

        #region Socket Listen->Accept->Receive->Process
        private void start_socket_server(int port, int backlog)
        {
            if (listenSocket != null)
            {
                listenSocket.Close();
                listenSocket = null;
            }

            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);
            listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            listenSocket.Bind(localEndPoint);
            listenSocket.Listen(backlog);

            System.Console.WriteLine(fetchcurrentTime() + ": Start Listen in " + port + ", " + backlog);
            StartAccept();
        }

        internal string fetchcurrentTime()
        {
            return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff:ffffff");
        }
        internal void StartAccept()
        {
            System.Console.WriteLine(fetchcurrentTime() + ": StartAccecpt. =================");
            SocketAsyncEventArgs acceptEventArg = CreateNewSaeaForAccept();
            try
            {
                bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);

                if (!willRaiseEvent)
                {
                    ProcessAccept(acceptEventArg);
                }
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(fetchcurrentTime() + ": StartAccept" + ex.Message + "\r\n" + ex.StackTrace);
                StartAccept();
            }
        }

        private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
        {
            ProcessAccept(e);
        }

        internal SocketAsyncEventArgs CreateNewSaeaForAccept()
        {
            //Allocate the SocketAsyncEventArgs object. 
            var acceptEventArg = new SocketAsyncEventArgs();
            acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);

            return acceptEventArg;
        }

        private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs)
        {
            System.Console.WriteLine(fetchcurrentTime() + ": ProcessAccept. ++++++++++++++");
            if (acceptEventArgs.SocketError != SocketError.Success)
            {
                System.Console.WriteLine(fetchcurrentTime() + ": connect error:acceptEventArgs.SocketError != SocketError.Success,SocketErrorType:" + acceptEventArgs.SocketError.ToString());
                StartAccept();
                return;
            }

            StartAccept();
            System.Console.WriteLine(fetchcurrentTime() + ": Receive Connect " + acceptEventArgs.AcceptSocket.RemoteEndPoint.ToString());
            Thread.Sleep(30000);

            SocketAsyncEventArgs tupleReceiveSendEventArgs = new SocketAsyncEventArgs();
            tupleReceiveSendEventArgs.Completed += IO_Completed;
            tupleReceiveSendEventArgs.AcceptSocket = acceptEventArgs.AcceptSocket;
            acceptEventArgs.AcceptSocket = null;

            StartReceive(tupleReceiveSendEventArgs);
        }

        void IO_Completed(object sender, SocketAsyncEventArgs e)
        {
            // determine which type of operation just completed and call the associated handler
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Receive:
                    {
                        ProcessReceive(e);
                        break;
                    }
                case SocketAsyncOperation.Send:
                    {
                        break;
                    }
                default:
                    {
                        //This exception will occur if you code the Completed event of some
                        //operation to come to this method, by mistake.
                        throw new ArgumentException("The last operation completed on the socket was not a receive or send");
                    }

            }
        }

        private void StartReceive(SocketAsyncEventArgs receiveEventArgs)
        {

            try
            {//debug
                byte[] buff = new byte[100];
                if (receiveEventArgs.AcceptSocket.Connected)
                {
                    receiveEventArgs.AcceptSocket.Receive(buff);
                }
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(fetchcurrentTime() + ": StartReceive" + "\r\n" + ex.Message + "\r\n" + ex.StackTrace);
            }

        }
        private void ProcessReceive(SocketAsyncEventArgs receiveEventArgs)
        {
            try
            {
                if (receiveEventArgs.SocketError != SocketError.Success)
                {
                    Console.WriteLine(fetchcurrentTime() + ": Process Receive SocketError.");
                    return;
                }

                if (receiveEventArgs.BytesTransferred == 0)
                {
                    Console.WriteLine(fetchcurrentTime() + ": Process Receive BytesTransferred is 0.");
                    return;
                }


                Int32 remainingBytesToProcess = receiveEventArgs.BytesTransferred;
                int availableBytes = remainingBytesToProcess;
                var byteArrayIn = new byte[availableBytes];

        
                Buffer.BlockCopy(receiveEventArgs.Buffer, 0, byteArrayIn, 0, remainingBytesToProcess);
                StartReceive(receiveEventArgs);
            }
            catch (Exception ex)
            {
                Console.WriteLine(fetchcurrentTime() + ": ProcessReceive" + ex.Message + "\r\n" + ex.StackTrace);
            }
        }
        #endregion Socket Listen->Accept->Receive->Process
    }
}

`

1, The backlog in Listen() is more than the concurrency number, but it seems invalid?

2, How to process the concurrency request successfully?

0

There are 0 best solutions below