Hi
In this post I will show how create a server using blocking socket in .net.
Reminder:
this implementation uses blocking socket and message that vary in length.
The server side is different from the client side in that it is passive and not active as the client, what that means is that the server reacted to the client i.e. if there is a connection problem and the server can not send an answer to the client it dose not retry ...it waits until the client reconnect and resend to answer.So what the server needs to do is manage it's answers in a way that connection problems will not cause messages to be lost.The server also has an obligation to close half open connections ,half open connection caused by clients that close the connection while the server is blocked on receive.
To manage answers in server you can number the answers in the server and implement a logical acknowledge of messages received by the client.
To handle the half open connection problem you can use time outs...
Now to our example:
First thing we need to open a socket that listens to connection request as so, what you see here the creation of a listening socket and binding it to an IP and port. The value 100 means that 100 clients can request to connect at any given time if 101 will request at the same time 1 will be left out.
After the listening socket is open the server is ready to receive clients, it dose this with the Accept method.Accept() creates a new socket dedicated to the new client with a new port.At first I thought that a firewall will deny the new connection but after testing the code it seams that the code works fine with firewall.
This is an Example of a server that collects client IP ....the clients reconnect to the server after a fix period of time, it the client dose not reconnect it is taken of the list.
Thats all for new....
In this post I will show how create a server using blocking socket in .net.
Reminder:
this implementation uses blocking socket and message that vary in length.
The server side is different from the client side in that it is passive and not active as the client, what that means is that the server reacted to the client i.e. if there is a connection problem and the server can not send an answer to the client it dose not retry ...it waits until the client reconnect and resend to answer.So what the server needs to do is manage it's answers in a way that connection problems will not cause messages to be lost.The server also has an obligation to close half open connections ,half open connection caused by clients that close the connection while the server is blocked on receive.
To manage answers in server you can number the answers in the server and implement a logical acknowledge of messages received by the client.
To handle the half open connection problem you can use time outs...
Now to our example:
First thing we need to open a socket that listens to connection request as so, what you see here the creation of a listening socket and binding it to an IP and port. The value 100 means that 100 clients can request to connect at any given time if 101 will request at the same time 1 will be left out.
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPEndPoint ipep = new IPEndPoint(IPAddress.Any, listenport);listener.Bind(ipep);listener.Listen(100);
After the listening socket is open the server is ready to receive clients, it dose this with the Accept method.Accept() creates a new socket dedicated to the new client with a new port.At first I thought that a firewall will deny the new connection but after testing the code it seams that the code works fine with firewall.
Socket client = listener.Accept();In order to send and receive using the socket please see my previews post.
This is an Example of a server that collects client IP ....the clients reconnect to the server after a fix period of time, it the client dose not reconnect it is taken of the list.
public class IpCollector{#region Private Membersprivate Socket listener;private Thread Listen;private volatile bool _stop;private int listenport;private Dictionary<string, DateTime> loginTime;private System.Timers.Timer CheckForClosedConnections;#endregion
#region Constructorpublic IpCollector(){loginTime = new Dictionary<string, DateTime>();CheckForClosedConnections = new System.Timers.Timer(1000 * 60 * 15);//15mCheckForClosedConnections.Elapsed += new System.Timers.ElapsedEventHandler(CheckForClosedConnections_Elapsed);}#endregion
#region Stop Startpublic void Start(int port){listenport = port;_stop = false;Listen = new Thread(listen);Listen.IsBackground = true;Listen.Start();CheckForClosedConnections.Start();}
public void Stop(){_stop = true;listener.Close();}#endregion
#region Thread Mian Entry Pointprivate void listen(){listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPEndPoint ipep = new IPEndPoint(IPAddress.Any, listenport);listener.Bind(ipep);listener.Listen(100);
while (!_stop){Socket client = listener.Accept();client.ReceiveTimeout = Settings.Default.TCP_SocketTimeOut;client.SendTimeout = Settings.Default.TCP_SocketTimeOut;IPAddress address = ((IPEndPoint)client.RemoteEndPoint).Address;string ipaddress = address.ToString();if (ReceiveAck(client)){if (SendAck(client)){lock (loginTime){if (!loginTime.ContainsKey(ipaddress)){loginTime.Add(ipaddress, DateTime.Now);}else{loginTime[ipaddress] = DateTime.Now;}}}CloseConnection(client);}}#endregion
#region Timer Elapsedvoid CheckForClosedConnections_Elapsed(object sender, System.Timers.ElapsedEventArgs e){TimeSpan closed = new TimeSpan(Settings.Default.CheckInIntervalInHours, 0, 0);//1hDateTime dt = DateTime.Now;List<string> closedclients = null;lock (loginTime){var closedconnections = from lt in loginTimewhere dt.Subtract(lt.Value) >= closedselect lt.Key;closedclients = closedconnections.ToList();foreach (var item in closedclients){loginTime.Remove(item);}}}#endregion
#region Public Methodpublic List<string> GetClients(){lock (loginTime){return loginTime.Keys.ToList();}}#endregion
#region TCP Helpprivate bool SendAck(Socket s){try{byte[] ack = BitConverter.GetBytes(true);int total, size, dataleft, sent;ack = ByteArrayHelper.CancatByteArray(BitConverter.GetBytes(ack.Length), ack);total = 0;size = ack.Length;dataleft = size;while (total < size)//send the object{sent = s.Send(ack, total, dataleft, SocketFlags.None);total += sent;dataleft -= sent;}return true;}catch (Exception ex){return false;}}
private bool ReceiveAck(Socket s){try{int total = 0;int recv = 0;int size = 0;byte[] datasize = new byte[4];while ((recv = s.Receive(datasize, 0, 4, 0)) < 4){if (recv == 0){//problemreturn false;}recv += s.Receive(datasize, 0, 4, 0);}size = BitConverter.ToInt32(datasize, 0);if (size == 1){int dataleft = size;byte[] data = new byte[size];while (total < size){if (recv == 0){//problemreturn false;}recv = s.Receive(data, total, dataleft, SocketFlags.None);total += recv;dataleft -= recv;}return BitConverter.ToBoolean(data, 0) == true;}return false;}catch (Exception ex){return false;}}
private void CloseConnection(Socket s){try{s.Shutdown(SocketShutdown.Both);}catch{
}s.Close();}#endregion}
Thats all for new....
אין תגובות:
הוסף רשומת תגובה