Please see code below, it is not very stable in my windows service, after starting for a while, it throw the error:
Exception is as below, Pls anybody help? Application:
REMSServerService.exe Framework Version: v4.0.30319 Description:
Unknown exception。 Info: System.Net.Sockets.SocketException Stack in
System.Net.Sockets.Socket.AcceptCallback(System.Object) in
System.Net.Sockets.Socket.RegisteredWaitCallback(System.Object,
Boolean) 在
System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object,
Boolean)
The error was catched on : readsize = listensocket2.Receive(buffer_receive);
The project is on a data communication center, the clients are GPRS DTU socket client.
Please help!!!
Part I:
protected override void OnStart(string[] args)
{
IPEndPoint endpoint = new IPEndPoint(RemsSocket.myip, RemsSocket.webport);
Socket listensocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listensocket.Bind(endpoint);
listensocket.Listen(200);
Thread th = new Thread(new ParameterizedThreadStart(RemsSocket.listen_send));
th.IsBackground = true;
th.Start(listensocket);
}
Part II:
public static void listen_send(object source)
{
while (true)
{
done.Reset();
Socket listensocket = (Socket)source;
listensocket.BeginAccept(new AsyncCallback(acceptcallback_send), listensocket);
done.WaitOne();
}
}
public static void acceptcallback_send(IAsyncResult ar)
{
done.Set();
Socket socket = (Socket)ar.AsyncState;
Socket listensocket2 = socket.EndAccept(ar);
byte[] buffer_validate = new byte[buffersize];
string hostcode = "";
byte[] buffer_send = Hex.HexStringToByteArray(validate_code);
listensocket2.Send(buffer_send, 0, buffer_send.Length, SocketFlags.None);
listensocket2.Receive(buffer_validate);
int readsize = buffer_validate.Length; //listensocket2.EndReceive(ar);
if (readsize > 0)
{
bool success = FirstValidate(buffer_validate, ref hostcode);
bool validate = BLL.ExtHostBLL.CanCommunicate(hostcode);
if (success && validate)
{
LoopSendReceive(hostcode, listensocket2);
}
}
}
Part III:
public static void LoopSendReceive(string hostcode, Socket listensocket2)
{
listensocket2.Blocking = true;
byte[] buffer_receive = new byte[buffersize];
bool validate = BLL.ExtHostBLL.CanCommunicate(hostcode);
while (validate)
{
Thread.Sleep(500);
int readsize;
bool success;
IPEndPoint clientipe = (IPEndPoint)listensocket2.RemoteEndPoint;
byte commandByte = Hex.HexStringToByteArray(command_8);
listensocket2.Send(commandByte, 0, commandByte.Length, SocketFlags.None);
listensocket2.ReceiveTimeout = 5000;
int countSocketException = 0;
readsize = listensocket2.Receive(buffer_receive);
if (readsize != 0)
{
clientipe = (IPEndPoint)listensocket2.RemoteEndPoint;
ClientDto client = hostList.FirstOrDefault(c => c.Ip == clientipe.Address.ToString());
ParseChannel.AlertStatus[] data;
ParseChannel channel = new ParseChannel();
success = channel.Parse(buffer_receive, client, out data);
if (!success)
{
continue;
}
SaveData(data, client);
}
}
}
Related
I am trying to make a message server and I have an error with this code:
The error "is only one use of each socket address can be normally permitted"
Server:
class Program
{
//Server Control
static bool stop = false;
static bool pause_listening = false;
//Server Info
static int port = 11000;
static string server_ip = null;
//User Declaration
static List<user> allUsers = new List<user>();
static int users = 0;
//IP Address
static IPAddress ipaddr;
static IPEndPoint localEP;
static IPEndPoint userportEP;
static IPEndPoint temp;
//Data
static string data = null;
static byte[] bytes = new Byte[1024];
//Threads
static Thread listener = new Thread(listen);
static Thread server_control = new Thread(Options);
static Thread UserPort = new Thread(addUserPort);
static void Main(string[] args)
{
Console.WriteLine("Message Server");
start();
}
static void start()
{
server_ip = input("What is your local IPv4 address");
ipaddr = IPAddress.Parse(server_ip);
allUsers.Add(new user());
allUsers[users].name = "Admin";
allUsers[users].ip = server_ip;
allUsers[users].desc = "Nimda";
allUsers[users].id = 0;
localEP = new IPEndPoint(ipaddr, port);
userportEP = new IPEndPoint(ipaddr, 1300);
UserPort.Start();
listener.Start();
server_control.Start();
}
static void addUserPort()
{
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and
// listen for incoming connections.
try
{
listener.Bind(userportEP);
listener.Listen(10);
Console.WriteLine("User Listener Started");
// Start listening for connections.
while (pause_listening || stop != true)
{
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
string value = null;
// An incoming connection needs to be processed.
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
value += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (value.IndexOf("<!EOM>") > -1)
{
Console.WriteLine("Someone Requested");
if(value.IndexOf( "!au") > -1)
{
String[] rawData = value.Split('|');
String[] userData = new String[3];
for(int x = 0; x < rawData.Length; x++)
{
String stringbuff = rawData[x];
if(stringbuff.IndexOf("name:") > -1)
{
var tempData = stringbuff.Split(':');
userData[x] = tempData[0];
}
else if (stringbuff.IndexOf("ipaddr:") > -1)
{
var tempData = stringbuff.Split(':');
userData[x] = tempData[1];
}
else if (stringbuff.IndexOf("desc:") > -1)
{
var tempData = stringbuff.Split(':');
userData[x] = tempData[2];
}
}
addUser(userData[0], userData[1], userData[2]);
}
break;
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
static void listen()
{
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
Console.WriteLine("Message Listener Started");
try
{
listener.Bind(localEP);
listener.Listen(10);
while (pause_listening || stop != true)
{
Socket handler = listener.Accept();
data = null;
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<!EOM>") > -1 && data.IndexOf("<!META>") > -1)
{
textSent(data);
break;
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
static void addUser(String name, String ip, String desc)
{
users++;
allUsers.Add(new user());
userportEP = new IPEndPoint(IPAddress.Parse(ip), 1300);
allUsers[users].name = name;
allUsers[users].ip = ip;
allUsers[users].desc = desc;
allUsers[users].id = users;
byte[] msg = Encoding.ASCII.GetBytes(string.Format("!Join<!PORT>{0}<!PORT><!EOM>", port));
Socket confirm = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
confirm.Bind(userportEP);
confirm.Connect(userportEP);
confirm.Send(msg);
confirm.Shutdown(SocketShutdown.Both);
confirm.Close();
}
static String input(String inputText)
{
Console.WriteLine(inputText);
return Console.ReadLine();
}
static void Options()
{
while(stop == false)
{
Console.Write("\n Server>>");
String command = Console.ReadLine();
switch (command)
{
case "stop":
stop = true;
listener.Abort();
UserPort.Abort();
StopServer();
break;
default:
Console.WriteLine("\t The command \"{0} \" is not valid", command);
break;
}
}
}
static void StopServer()
{
Console.WriteLine("Server is stopping");
Console.Read();
}
static void textSent(String text)
{
String[] rawText = text.Split(new string[] { "<!META>" }, StringSplitOptions.None) ;
String message = rawText[0];
String[] meta = rawText[1].Split(':');
String package = meta[0] + ": " + message + "<!EOM>";
SendToAll(package);
}
static void SendToAll(String pack)
{
byte[] msg = Encoding.ASCII.GetBytes(pack);
Socket send_socket= new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
for (int x = 0; allUsers.Count < x; x++)
{
temp = new IPEndPoint(IPAddress.Parse(allUsers[x].ip), port);
send_socket.Bind(temp);
send_socket.Connect(temp);
send_socket.Send(msg);
}
send_socket.Shutdown(SocketShutdown.Both);
send_socket.Close();
}
}
Client:
class Program
{
static int port;
static string server_ip;
static string ign;
static string desc;
static string ip;
static bool connected = false;
static bool exit = false;
static IPEndPoint remoteEP;
static IPEndPoint remoteUserRequestEP;
static IPEndPoint localEP;
static IPEndPoint userRequestListen;
static Socket listen;
static Socket send;
static Thread listenThread;
static Thread sendThread;
static void Main(string[] args)
{
Console.WriteLine("Message Client");
start();
}
static void start()
{
server_ip = input("Please Enter your Server I.P.");
remoteUserRequestEP = new IPEndPoint(IPAddress.Parse(server_ip), 1300);
ip = input("Enter your local IPv4 Address");
desc = input("Enter a short description");
ign = input("Enter a name to represent yourself");
localEP = new IPEndPoint(IPAddress.Parse(ip), 11000);
userRequestListen = new IPEndPoint(IPAddress.Parse(ip), 1300);
listenThread = new Thread(listening);
sendThread = new Thread(createSend);
listenThread.Start();
sendThread.Start();
}
static String input(String inputText)
{
Console.WriteLine(inputText);
return Console.ReadLine();
}
static void listening()
{
listen = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
String data;
byte[] bytes;
try
{
listen.Bind(localEP);
listen.Listen(1);
while (exit == false)
{
Socket handler = listen.Accept();
data = null;
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<!EOM>") > -1 )
{
string finalMSG = data.Replace("<!EOM>", null);
Console.WriteLine(finalMSG);
break;
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
static void requestAcesss()
{
byte[] msg = new byte[1024];
msg = Encoding.ASCII.GetBytes(string.Format("!au|name:{0}|ipaddr:{1}|desc:{2}|<!EOM>", ign, ip, desc));
Socket usrRequest = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
usrRequest.Bind(userRequestListen);
usrRequest.Connect(userRequestListen);
usrRequest.Send(msg);
try {
while (connected == false)
{
Socket handler = usrRequest.Accept();
string value = null;
while (true)
{
byte[] bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
value += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (value.IndexOf("<!EOM>") > -1)
{
String[] raw = value.Split(new string[] { "<!PORT>" }, StringSplitOptions.None);
port = Int32.Parse(raw[1]);
remoteEP = new IPEndPoint(IPAddress.Parse(server_ip), port);
localEP = new IPEndPoint(IPAddress.Parse(ip), port);
Console.WriteLine(port);
connected = true;
startServices();
}
break;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
static void createSend()
{
byte[] msg = new byte[1024];
send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
while(exit == false)
{
string raw = Console.ReadLine();
if (raw == "exit")
{
exit = true;
listenThread.Abort();
sendThread.Abort();
stop();
break;
}
string finalmsg = string.Format( raw + "<!META>name:{0}<!META><!EOM>", ign);
send.Bind(localEP);
msg = Encoding.ASCII.GetBytes(finalmsg);
send.Send(msg);
}
send.Shutdown(SocketShutdown.Both);
send.Close();
}
static void startServices()
{
listenThread.Start();
sendThread.Start();
}
static void stop()
{
Console.WriteLine("Press any key to terminate");
Console.ReadLine();
}
}
The sockets aren't used twice nor does a thread get started twice.
Having the same error, I came looking for an answer. Finally found it myself:
An earlier instance of the process may still be running, if you didn't stop it well, e.g. using just Ctrl+C.
I am currently working on a simple udp client/server system, and I stumbled upon the following: When I try to get the IP of IPEndPoint (which I fetched using IPAdress.Any)in a program using UdpClient it works and I get the following result (the top one):
But when I use a normal socket instead of a UdpClient it somehow fails to distinguish the clients/IPs (bottom one). The code for both is listed below. The reason I would like to use sockets is because using the same class for both sending and receiving (not the same instance) is convenient and makes the code far more understandable.
First
bool messageReceived = false;
bool done = false;
const int listenPort = 11000;
UdpClient listener = new UdpClient(listenPort);
IPEndPoint receiveEP = new IPEndPoint(IPAddress.Any, listenPort);
string[] adresses = new string[2];
public void ReceiveCallback(IAsyncResult ar)
{
int id = 0;
Byte[] receiveBytes = listener.EndReceive(ar, ref receiveEP);
for (int i = 0; i < adresses.Length; i++)
{
if (adresses[i] == receiveEP.Address.ToString())
{
id = i;
break;
}
else if (adresses[i] == null)
{
id = i;
adresses[i] = receiveEP.Address.ToString();
break;
}
}
byte[] a= Encoding.ASCII.GetBytes("Is anybody there?");
listener.Send(a, a.Length, receiveEP);
Console.WriteLine("Received message from {0} (client {1}):", adresses[id],id);
string receiveString = Encoding.ASCII.GetString(receiveBytes);
if (receiveString == "stop")
{
done = true;
}
Console.WriteLine("Received: {0}", receiveString);
messageReceived = true;
}
public void ReceiveMessages()
{
Console.WriteLine("listening for messages");
while(!done){
try
{
messageReceived = false;
if (!messageReceived)
{
listener.BeginReceive(new AsyncCallback(ReceiveCallback), null);
}
while (!messageReceived)
{
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Console.WriteLine("Done receiving messages...");
for (int i = 0; i < adresses.Length; i++)
{
if (adresses[i] != null)
{
Console.WriteLine(adresses[i]);
}
}
Console.ReadLine();
listener.Close();
}'
Second
bool messageReceived = false;
bool done = false;
const int listenPort = 11000;
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint receiveEP = new IPEndPoint(IPAddress.Any, listenPort);
string[] adresses = new string[2];
byte[] buffer = new byte[1024];
public void ReceiveMessages()
{
listener.Bind(receiveEP);
Console.WriteLine("listening for messages");
while (!done)
{
try
{
messageReceived = false;
if (!messageReceived)
{
listener.BeginReceive(buffer, 0,1024,SocketFlags.None,new AsyncCallback(ReceiveCallback), null);
}
while (!messageReceived)
{
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Console.WriteLine("Done receiving messages...");
for (int i = 0; i < adresses.Length; i++)
{
if (adresses[i] != null)
{
Console.WriteLine(adresses[i]);
}
}
Console.ReadLine();
listener.Close();
}
public void ReceiveCallback(IAsyncResult ar)
{
int id = 0;
int read = listener.EndReceive(ar);
for (int i = 0; i < adresses.Length; i++)
{
if (adresses[i] == receiveEP.Address.ToString())
{
id = i;
break;
}
else if (adresses[i] == null)
{
id = i;
adresses[i] = receiveEP.Address.ToString();
break;
}
}
Console.WriteLine("Received message from {0} (client {1}):", adresses[id], id);
string receiveString = Encoding.ASCII.GetString(buffer,0,read);
if (receiveString == "stop")
{
done = true;
}
Console.WriteLine("Received: {0}", receiveString);
messageReceived = true;
}'
I've already tried Socket.ReceiveMessageFrom() and using the packetinfo it returned but I ended up with the ip4 of the server even when I send from another machine. Could someone help me out?
Even though this was never supposed to be a Q/A type of question, I've found a way of getting it to work, which means receive() changes the groupEP to the IP of the data packet's sender by just using a Socket instead of an UdpClient (I mimicked the way an UdpClient works). At the moment, it's still synchronous (listener.Receive() is a blocking call) but that will be changed in the near future:
private const int listenPort = 11000;
public static int Main()
{
bool done = false;
Listener listener = new Listener(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
byte[] buffer = new byte[2048];
string received_data;
try
{
while (!done)
{
Console.WriteLine("Waiting for broadcast");
buffer=listener.Receive(ref groupEP);
received_data = Encoding.ASCII.GetString(buffer);
Console.WriteLine("Received a broadcast from {0}: {1}", groupEP.ToString(), received_data);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
return 0;
}
}
public class Listener
{
public Socket client;
public AddressFamily adressFamily;
byte[] byte_buffer = new byte[2048];
public int port;
public Listener(int p)
{
port=p;
adressFamily = AddressFamily.InterNetwork;
IPEndPoint localEP;
localEP = new IPEndPoint(IPAddress.Any, port);
client = new Socket(this.adressFamily, SocketType.Dgram, ProtocolType.Udp);
client.Bind(localEP);
}
public byte[] Receive(ref IPEndPoint remoteEP)
{
IPEndPoint ipEndPoint=new IPEndPoint(IPAddress.Any,port);
EndPoint endPoint = (EndPoint)ipEndPoint;
int num = client.ReceiveFrom(byte_buffer, 2048, SocketFlags.None, ref endPoint);
remoteEP = (IPEndPoint)endPoint;
if (num < 2048)
{
byte[] array = new byte[num];
Buffer.BlockCopy(byte_buffer, 0, array, 0, num);
return array;
}
return byte_buffer;
}
I am trying to create asynchronous socket client in multithreaded environment but it is not working correctly.
As below sample code,
If i create new AsyncSocketClient and call StartClent from multi-threaded environment it will process only one or two for rest, it is not processing.(I am creating new AsyncSocketClient with every new request)
Is it because of static variables,
class AsyncSocketClient
{
private static AutoResetEvent sendDone =
new AutoResetEvent(false);
private static AutoResetEvent receiveDone =
new AutoResetEvent(false);
private static ManualResetEvent connectDone =
new ManualResetEvent(false);
static private String response = "";
public void StartClent()
{
Socket workSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// clientSock.ReceiveTimeout = 1;
try
{
workSocket.BeginConnect(new IPEndPoint(IPAddress.Loopback, 8080), new AsyncCallback(ConnectCallBack), workSocket);
connectDone.WaitOne();
Send(s.workSocket, "<EOF>");
sendDone.WaitOne();
Receive(workSocket);
receiveDone.WaitOne();
}
catch(Exception ex)
{
}
}
private void ConnectCallBack(IAsyncResult ar)
{
Socket workSocket = (Socket)ar.AsyncState;
workSocket.EndConnect(ar);
connectDone.Set();
}
private void Receive(Socket client)
{
StateObject state = new StateObject();
state.workSocket = client;
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallBack), state);
}
private void ReceiveCallBack(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
int byteReceived= client.EndReceive(ar);
if (byteReceived > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, state.buffer.Length));
Array.Clear(state.buffer, 0, state.buffer.Length);
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallBack), state);
}
else
{
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
receiveDone.Set();
}
}
private void Send(Socket client,string data)
{
byte[] sendBufer = Encoding.ASCII.GetBytes(data);
client.BeginSend(sendBufer, 0, sendBufer.Length, 0, new AsyncCallback(BeginSendCallBack), client);
}
private void BeginSendCallBack(IAsyncResult ar)
{
Socket client = (Socket)ar.AsyncState;
int byteSent= client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", byteSent);
sendDone.Set();
}
}
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 30;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
Here is an example of a non blocking client and server with a simple echo implemented. There is no error checking and nothing is closed correctly which should be done. The server has some synchronous code just to make it easier to follow.
Client
public class AsyncClient
{
private const int Port = 9999;
private readonly string _clientId;
private readonly Random _random;
public AsyncClient(int clientId)
{
_clientId = string.Format("Client Id: {0}", clientId);
_random = new Random(clientId);
}
public void StartClient()
{
try
{
var workSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var state = new ClientState { WorkSocket = workSocket };
workSocket.BeginConnect(new IPEndPoint(IPAddress.Loopback, Port), ConnectCallBack, state);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void ConnectCallBack(IAsyncResult ar)
{
var state = (ClientState) ar.AsyncState;
state.WorkSocket.EndConnect(ar);
Send(state);
}
private void Receive(ClientState clientState)
{
clientState.WorkSocket.BeginReceive(clientState.Buffer, 0, ClientState.BufferSize, 0, ReceiveCallBack, clientState);
}
private void ReceiveCallBack(IAsyncResult ar)
{
var state = (ClientState) ar.AsyncState;
Socket client = state.WorkSocket;
int byteReceived= client.EndReceive(ar);
if (byteReceived > 0)
{
var receivedString = Encoding.UTF8.GetString(state.Buffer, 0, byteReceived);
Console.WriteLine("From Server: " + receivedString);
Array.Clear(state.Buffer, 0, state.Buffer.Length);
state.Count++;
Thread.Sleep(1000 + _random.Next(2000));
Send(state);
}
}
private void Send(ClientState clientState)
{
Console.WriteLine("Sending " + _clientId);
byte[] buffer = Encoding.UTF8.GetBytes(string.Format("Send from Thread {0} Client id {1} Count {2}", Thread.CurrentThread.ManagedThreadId, _clientId,clientState.Count));
clientState.WorkSocket.BeginSend(buffer, 0, buffer.Length, 0, BeginSendCallBack, clientState);
}
private void BeginSendCallBack(IAsyncResult ar)
{
var state = (ClientState) ar.AsyncState;
int byteSent= state.WorkSocket.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", byteSent);
Receive(state);
}
}
public class ClientState
{
// Client socket.
public Socket WorkSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] Buffer = new byte[BufferSize];
public int Count = 0;
}
Server
public class AsyncServer
{
private const int Port = 9999;
public void StartServer()
{
var thread = new Thread(Run) {IsBackground = true};
thread.Start();
}
private void Run()
{
Console.WriteLine("Running");
var tcpListener = new TcpListener(IPAddress.Loopback, Port);
tcpListener.Start();
while (true)
{
Console.WriteLine("Before Accept");
var state = new ServerState {WorkSocket = tcpListener.AcceptSocket()};
Console.WriteLine("Before Recieve");
Receive(state);
}
}
private void Receive(ServerState state)
{
state.WorkSocket.BeginReceive(state.Buffer, 0, ServerState.BufferSize, 0, ReceiveCallBack, state);
}
private void ReceiveCallBack(IAsyncResult ar)
{
Console.WriteLine("ReceiveCallBack");
var state = (ServerState) ar.AsyncState;
try
{
int byteReceived= state.WorkSocket.EndReceive(ar);
if (byteReceived > 0)
{
var receivedString = Encoding.UTF8.GetString(state.Buffer, 0, byteReceived);
Console.WriteLine("Received: " + receivedString);
var bytesToSend = Encoding.UTF8.GetBytes("Server Got --> " + receivedString);
Array.Copy(bytesToSend, state.Buffer, bytesToSend.Length);
state.WorkSocket.Send(state.Buffer, 0, bytesToSend.Length, SocketFlags.None);
Array.Clear(state.Buffer, 0, state.Buffer.Length);
Receive(state);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private class ServerState
{
public const int BufferSize = 1024;
public readonly byte[] Buffer = new byte[1024];
public Socket WorkSocket;
}
I have run this using a console you can either have two applications or just launch the client and server separately.
static void Main(string[] args)
{
if (args.Length != 0)
{
var server = new AsyncServer();
server.StartServer();
}
else
{
for(int i = 0; i < 10; i++)
{
var client = new AsyncClient(i);
client.StartClient();
}
}
Console.WriteLine("Press a key to exit");
Console.ReadKey();
}
I have the the following two scenarios that I am testing and one works but the other does not.
I have socket server and socket client application running on two different machines
both the scenarios are using the socketasynceventargs
Scenario 1 (Works)
create 40k socket clients in a loop, wait for all connections to be established and then all clients send messages to the server at the same time and receive response from the server 10 times(i.e. send/receive happens 10 times).
Scenario 2 (Does not work. I get a lot of connection refusal errors)
create 40k socket clients in a loop and send/receive the same 10 messages to the server as soon as each client is connected instead of waiting for the 40k connections to be established.
I cant figure out why my second scenario would fail. i understand that in scenario 1 the server is not doing much until all the 40k connections are made. but it is able to communicate with all the clients at the same time. any ideas??
Thank you for you patience.
here is the socket server code
public class SocketServer
{
private static System.Timers.Timer MonitorTimer = new System.Timers.Timer();
public static SocketServerMonitor socket_monitor = new SocketServerMonitor();
private int m_numConnections;
private int m_receiveBufferSize;
public static BufferManager m_bufferManager;
Socket listenSocket;
public static SocketAsyncEventArgsPool m_readWritePool;
public static int m_numConnectedSockets;
private int cnt = 0;
public static int Closecalled=0;
public SocketServer(int numConnections, int receiveBufferSize)
{
m_numConnectedSockets = 0;
m_numConnections = numConnections;
m_receiveBufferSize = receiveBufferSize;
m_bufferManager = new BufferManager(receiveBufferSize * numConnections ,
receiveBufferSize);
m_readWritePool = new SocketAsyncEventArgsPool(numConnections);
}
public void Init()
{
MonitorTimer.Interval = 30000;
MonitorTimer.Start();
MonitorTimer.Elapsed += new System.Timers.ElapsedEventHandler(socket_monitor.Log);
m_bufferManager.InitBuffer();
SocketAsyncEventArgs readWriteEventArg;
for (int i = 0; i < m_numConnections; i++)
{
readWriteEventArg = new SocketAsyncEventArgs();
m_readWritePool.Push(readWriteEventArg);
}
}
public void Start(IPEndPoint localEndPoint)
{
listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(localEndPoint);
listenSocket.Listen(1000);
StartAccept(null);
}
public void Stop()
{
if (listenSocket == null)
return;
listenSocket.Close();
listenSocket = null;
Thread.Sleep(15000);
}
private void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
if (acceptEventArg == null)
{
acceptEventArg = new SocketAsyncEventArgs();
acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
}
else
{
// socket must be cleared since the context object is being reused
acceptEventArg.AcceptSocket = null;
}
try
{
bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);
if (!willRaiseEvent)
{
ProcessAccept(acceptEventArg);
}
}
catch (Exception e)
{
}
}
void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);
}
private void ProcessAccept(SocketAsyncEventArgs e)
{
Interlocked.Increment(ref m_numConnectedSockets);
socket_monitor.IncSocketsConnected();
SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();
m_bufferManager.SetBuffer(readEventArgs);
readEventArgs.UserToken = new AsyncUserToken { id = cnt++, StarTime = DateTime.Now };
readEventArgs.AcceptSocket = e.AcceptSocket;
SocketHandler handler=new SocketHandler(readEventArgs);
StartAccept(e);
}
}
class SocketHandler
{
private SocketAsyncEventArgs _socketEventArgs;
public SocketHandler(SocketAsyncEventArgs socketAsyncEventArgs)
{
_socketEventArgs = socketAsyncEventArgs;
_socketEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
StartReceive(_socketEventArgs);
}
private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs)
{
bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
if (!willRaiseEvent)
{
ProcessReceive(receiveSendEventArgs);
}
}
private void ProcessReceive(SocketAsyncEventArgs e)
{
// check if the remote host closed the connection
AsyncUserToken token = (AsyncUserToken)e.UserToken;
//token.StarTime = DateTime.Now;
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
// process the data here
//reply to client
byte[] AckData1 = BitConverter.GetBytes(1);
SendData(AckData1, 0, AckData1.Length, e);
StartReceive(e);
}
else
{
CloseClientSocket(e);
}
}
private 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:
ProcessSend(e);
break;
default:
throw new ArgumentException("The last operation completed on the socket was not a receive or send");
}
}
private void CloseClientSocket(SocketAsyncEventArgs e)
{
AsyncUserToken token = e.UserToken as AsyncUserToken;
// close the socket associated with the client
try
{
e.AcceptSocket.Shutdown(SocketShutdown.Send);
}
catch (Exception ex)
{
}
e.AcceptSocket.Close();
Interlocked.Decrement(ref SocketServer.m_numConnectedSockets);
SocketServer.socket_monitor.DecSocketsConnected();
SocketServer.m_bufferManager.FreeBuffer(e);
e.Completed -= new EventHandler<SocketAsyncEventArgs>(IO_Completed);
SocketServer.m_readWritePool.Push(e);
}
public void SendData(Byte[] data, Int32 offset, Int32 count, SocketAsyncEventArgs args)
{
try
{
Socket socket = args.AcceptSocket;
if (socket.Connected)
{
var i = socket.Send(data, offset, count, SocketFlags.None);
}
}
catch (Exception Ex)
{
}
}
}
here is the client code that throws the error in the connectcallback method
// State object for receiving data from remote device.
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
public int count = 0;
}
public class AsynchronousClient
{
// The port number for the remote device.
private const int port = 11000;
private static int closecalled = 0;
private static bool wait = true;
// ManualResetEvent instances signal completion.
private static ManualResetEvent connectDone =
new ManualResetEvent(false);
private static ManualResetEvent sendDone =
new ManualResetEvent(false);
private static ManualResetEvent receiveDone =
new ManualResetEvent(false);
// The response from the remote device.
private static String response = String.Empty;
private static void StartClient(Socket client, IPEndPoint remoteEP)
{
// Connect to a remote device.
try
{
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), new StateObject { workSocket = client });
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
StateObject state = (StateObject)ar.AsyncState;
var client = state.workSocket;
// Complete the connection.
client.EndConnect(ar);
var data = "AA5500C08308353816050322462F01020102191552E7D3FA52E7D3FB1FF85BF1FE9F201000004AB80000000500060800001EFFB72F0D00002973620000800000FFFFFFFF00009D6D00003278002EE16D0000018500000000000000000000003A0000000100000000828C80661FF8B436FE9EA9FC000000120000000700000000000000000000000400000000000000000000000000000000000000000000281E0000327800000000000000000000000000AF967D00000AEA000000000000000000000000";
Send(state, data);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(StateObject state)
{
try
{
Socket client = state.workSocket;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
//if (wait)
//{
// connectDone.WaitOne();
//}
if (bytesRead > 0)
{
state.count = state.count + 1;
byte[] b = new byte[bytesRead];
Array.Copy(state.buffer, b, 1);
if (b[0] == 1)
{
if (state.count < 10)
{
var data = "AA5500C08308353816050322462F01020102191552E7D3FA52E7D3FB1FF85BF1FE9F201000004AB80000000500060800001EFFB72F0D00002973620000800000FFFFFFFF00009D6D00003278002EE16D0000018500000000000000000000003A0000000100000000828C80661FF8B436FE9EA9FC000000120000000700000000000000000000000400000000000000000000000000000000000000000000281E0000327800000000000000000000000000AF967D00000AEA000000000000000000000000";
Send(state, data);
}
else
{
Interlocked.Increment(ref closecalled);
Console.WriteLine("closecalled:-" + closecalled + " at " + DateTime.Now);
client.Close();
}
}
else
{
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
}
else
{
client.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(StateObject state, String data)
{
try
{
Socket client = state.workSocket;
var hexlen = data.Length;
byte[] byteData = new byte[hexlen / 2];
int[] hexarray = new int[hexlen / 2];
int i = 0;
int k = 0;
//create the byte array
while (i < data.Length / 2)
{
string first = data[i].ToString();
i++;
string second = data[i].ToString();
string x = first + second;
byteData[k] = (byte)Convert.ToInt32(x, 16);
i++;
k++;
}
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
Receive(state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main(String[] args)
{
Start();
Console.ReadLine();
return 0;
}
private static void Start()
{
IPAddress ipaddress = IPAddress.Parse("10.20.2.152");
IPEndPoint remoteEP = new IPEndPoint(ipaddress, port);
for (int i = 0; i < 40000; i++)
{
Thread.Sleep(1);
// Create a TCP/IP socket.
try
{
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
StartClient(client, remoteEP);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
if (i == 39999)
{
Console.WriteLine("made all conns at " + DateTime.Now);
}
}
}
}
I would use a linear queue to accept incoming connections. Something like this:
public async Task Accept40KClients()
{
for (int i = 0; i < 40000; i++)
{
// Await this here -------v
bool willRaiseEvent = await listenSocket.AcceptAsync(acceptEventArg);
if (!willRaiseEvent)
{
ProcessAccept(acceptEventArg);
}
}
}
If that's not fast enough, maybe you can do 10 waits at a time, but I think this is good enough... I might be wrong on this though.
I am using this class to send an Echo test from/to my application
public class SocketClient
{
Socket socket = null;
static ManualResetEvent clientDone = new ManualResetEvent(false);
const int TIMEOUT_MILLISECONDS = 5000;
const int MAX_BUFFER_SIZE = 2048;
public SocketClient()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
public string Send(string serverName, int portNumber, string data)
{
string response = "Timeout";
if (socket != null)
{
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = new DnsEndPoint(serverName, portNumber);
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
response = e.SocketError.ToString();
clientDone.Set();
});
byte[] payload = Encoding.UTF8.GetBytes(data);
socketEventArg.SetBuffer(payload, 0, payload.Length);
clientDone.Reset();
socket.SendToAsync(socketEventArg);
clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "not initialized";
}
return response;
}
public string Recieve(int portNumber)
{
string response = "Timeout";
if (socket != null)
{
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response.Trim('\0');
}
else
{
response = e.SocketError.ToString();
}
clientDone.Set();
});
socketEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, portNumber);
clientDone.Reset();
socket.ReceiveFromAsync(socketEventArg);
clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
return response;
}
public void Close()
{
socket.Close();
}
}
and here's how I use it:
SocketClient client = new SocketClient();
client.Send("192.168.1.2",77 , "besm ellah");
textBox1.Text=client.Recieve(77);
It always through Argument Exception was unhandled at socket.SendToAsync(socketEventArg);
"The parameter remoteEP must not be of type DnsEndPoint."
"Parameter name: remoteEP"
I enabled the feature of simple TCP/IP on windows features, but it also doesn't work.
-UPDATE-
I tried changing the code to be:
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
socketEventArg.RemoteEndPoint = new IPEndPoint(localIPs[3], portNumber);
it doesn't give an exception, but the message doesn't get through.
Well, it looks like you should change it to be a different type of endpoint, rather than DNS endpoint.
I think you should be using an IPEndPoint
http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx