Server Side
If you have understood whatever I have described so far, you will easily understand the Server part of the socket application. So far we have been talking about a client making connection to a server and sending and receiving data.
On the Server end, the application has to send and receive data. But in addition to adding and receiving data, server has to allow the clients to make connections by listening at some port. Server does not need to know client I.P. addresses. It really does not care where the client is because its not the server but client who is responsible for making connection. Server's responsibility is to manage client connections.
On the server side there has to be one socket called the Listener socket that listens at a specific port number for client connections. When the client makes a connection, the server needs to accept the connection and then in order for the server to send and receive data from that connected client it needs to talk to that client through the socket that it got when it accepted the connection. The following code illustrates how server listens to the connections and accepts the connection:
public Socket m_socListener;
public void
StartListening()
{
try
{
//create the listening
socket...
m_socListener = new
Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint ( IPAddress.Any ,8221);
//bind
to local IP Address...
m_socListener.Bind( ipLocal );
//start listening...
m_socListener.Listen (4);
// create
the call back for any client connections...
m_socListener.BeginAccept(new AsyncCallback ( OnClientConnect ),null);
cmdListen.Enabled = false;
}
catch(SocketException se)
{
MessageBox.Show ( se.Message );
}
}
If you look at the above code carefully you will see that its similar to we
did in the asynchronous client. First of all the we need to create a listening
socket and bind it to a local IP address. Note that we have given Any as the
IPAddress (I will explain what it means later), and we have passed the port
number as 8221. Next we made a call to Listen
function. The 4 is a
parameter indicating backlog indicating the maximum length of the queue of
pending connections.
Next we made a call to BeginAccept
passing it a delegate
callback. BeginAccept
is a non-blocking method that returns
immediately and when a client has made requested a connection, the callback
routine is called and you can accept the connection by calling
EndAccept
. The EndAccept
returns a socket object which
represents the incoming connection. Here is the code for the callback
delegate:
public void OnClientConnect(IAsyncResult asyn)
{
try
{
m_socWorker = m_socListener.EndAccept (asyn);
WaitForData(m_socWorker);
}
catch(ObjectDisposedException)
{
System.Diagnostics.Debugger.Log(0,"1","
OnClientConnection:
Socket has been closed
");
}
catch(SocketException se)
{
MessageBox.Show ( se.Message );
}
}
Here we accept the connection and call WaitForData
which in turn
calls BeginReceive
for the m_socWorker.
If we want to send data some data to client we use m_socWorker socket for that purpose like this:
Object objData = txtDataTx.Text;
byte[] byData =
System.Text.Encoding.ASCII.GetBytes(objData.ToString ());
m_socWorker.Send
(byData);