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?