First open your desired compiler. I'm using Visual Studio 2010 in this tutorial. It can be downloaded from
. It is free to download but it is only beta version at the moment so it's not final and it might have (and it does have) some bugs. However you can use one of the earlier versions or Visual Studio C# Express Edition, doesn't matter.When you have installed the compiler (If you didn't have it) at top you see "File" click there and choose New -> Project. Now because we're creating a DLL in this example choose the Class Library option from the list. In Visual Studio you have to make sure that you have chosen the Visual C# tab from the list before you see those choices. (Well other languages in list have it also but we're developing with C# now.)
Choose a proper name for it, I'm using 'SocketLib' in this example, you can name it pretty much everything you want. (Can't contain any special characters though like ~)
Alright. Some of you may be lost on what to do next. First we need to get access to the already built Socket class that Microsoft has been nice enough to give. For that we need to add following lines in the very top of the SocketLib.cs file. (If the name isn't this you can change it from the right side, right click Class1.cs and rename it to SocketLib.cs)
PHP Code:
using System;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.Collections.Generic;
System.Net gives us access to a class named IPAddress, we're going to need it for later when we bind the socket and start listening for incoming connections.
System.Net.Socket is the very base of this program, it'll provide us a Socket class which is used to communicate with other computers over net. Ofcourse you could wrap the ws2_32.dll directly for send/recv and create your own socket structure
System.Threading is used for Threads, obviously. It's not adviced to do like I'm going to show you to do in large scale. We're going to have one thread for listening connections and another one to receive data from the connected clients.
System.Collections.Generic is used to access List<T>, where T is a type of items to be saved, in this example we're gonna use it to keep track of connected clients.
Alright enough chatting, it's time to get into actual coding. I know how boring these long reads can be but I hope it'll help you to understand some of the code I'm going to show next. We need to add a class. I'll name it ServerSocket so add it there with public accessor (so you can actually use it from outside the dll) now the code should look like this.
PHP Code:
using System;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.Collections.Generic;
namespace SocketLib
{
public class ServerSocket
{
}
}
Alright, like I told earlier Socket is used to communicate with other clients over the net. (Or why not communicate with socket in your own computer, irrelevant in this tutorial though.) We need to add a Socket variable in our ServerSocket class to communicate with the clients connecting to our server.
We also need to specify the port we're going to use for listening.
We're also going to need something for the threads and for triggering the connections events. We also need to add a constructor and destructor for the class. The code should look similar to this now
PHP Code:
public class ServerSocket
{
private ushort port;
private Socket connection;
private List<Socket> clients;
private Thread acceptThread;
private Thread receiveThread;
public SocketEvent<Socket, object> OnClientConnect, OnClientDisconnect;
public SocketEvent<Socket, byte[]> OnClientReceive;
public ServerSocket(ushort Port)
{
port = Port;
connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
~ServerSocket()
{
if (acceptThread != null)
acceptThread.Abort();
if (receiveThread != null)
receiveThread.Abort();
}
}
Now ofcourse we need to add method to actually start the server we have only initialized the vital variables now. We create a method 'Start' that takes not parameters and returns nothing. (as in we're going to use void for it.) You need to add the following code inside the ServerSocket class
PHP Code:
public void Start()
{
if (enabled)
{
string ExceptionMessage = string.Format("Server is already running on port {0}.", port);
throw new Exception(ExceptionMessage);
}
connection.Bind(new IPEndPoint(IPAddress.Any, port));
connection.Listen(100);
enabled = true;
acceptThread = new Thread(new ThreadStart(AcceptFunction));
receiveThread = new Thread(new ThreadStart(ReceiveFunction));
acceptThread.Start();
receiveThread.Start();
}
connection.Listen in other hand starts the listening, the parameter you give to it is the amount of pending connections in queue.
We haven't initialized the thread variables so we're going to do it now and give them a parameter. The parameter is the function we're gonna use that thread for. At the moment the compiler might give you an error that there is no such functions like AcceptFunction or ReceiveFunction, lets correct these errors. We add them.
I'm going to discuss AcceptFunction at first. We need to make sure that the functions gets executed as long as the enabled is set to true. We create a while loop. Like this
PHP Code:
private void AcceptFunction()
{
while (enabled)
{
}
}
so the accept function should look like this now
PHP Code:
private void AcceptFunction()
{
while (enabled)
{
Socket client = connection.Accept();
if (client == null)
continue;
if (OnClientConnect != null)
OnClientConnect(client, null);
clients.Add(client);
Thread.Sleep(1);
}
}
Now we need to go through the sockets one by one and see whether they have data to send or not. We create three variables, one to determine whether the connection has been lost, one to receive the data on (byte[]) and one to determine the length of the received data. If the length is equal to 0 it means that the connection has been lost and we need to set the remove to true. Receive length is -1 if there is not data available but the connection isn't lost. So we need to check whether the length is greater than 0.
If the length is greater than 0 we need to create a new byte[] buffer for the packet. Since we gave the first one the default size of 8192 it'll contain (8192 - Length) bytes of empty (0's)
Now the ReceiveFunction should look like this.
PHP Code:
private void ReceiveFunction()
{
while (true)
{
for (int i = 0; i < clients.Count; i++)
{
Socket client = clients[i];
if (client == null) // Shouldn't happen since we don't allow adding null variables to the List in the accept function.
break;
bool remove = false;
byte[] recvBuffer = new byte[8192];
int recvLength = client.Receive(recvBuffer, 8192, SocketFlags.None);
if (recvLength == 0)
remove = true;
else if (recvLength > 0)
{
byte[] packet = new byte[recvLength];
Array.Copy(recvBuffer, packet, recvLength);
if (OnClientReceive != null)
OnClientReceive(client, packet);
packet = null;
}
if (remove)
{
if (OnClientDisconnect != null)
{
OnClientDisconnect(client, null);
clients.RemoveAt(i);
i--;
}
}
}
Thread.Sleep(1);
}
}
PHP Code:
public void Stop()
{
if (enabled)
{
for (int i = 0; i < clients.Count; i++)
{
if (OnClientDisconnect != null)
{
Socket client = clients[i];
OnClientDisconnect(client, null);
if (client.Connected)
{
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
}
connection = null;
clients.Clear();
enabled=false;
acceptThread.Abort();
receiveThread.Abort();
}
}
That was it. I'm not going to post the full code so people could just copy paste it. However imma still show how to actually use this.
PHP Code:
public static void Main(string[] args)
{
ServerSocket ss = new ServerSocket(9958);
ss.OnClientConnect = OnClientConnect;
ss.OnClientDisconnect = OnClientDisconnect;
ss.OnClientReceive = OnClientReceive;
ss.Start();
}
public static void OnClientConnect(Socket Sender, object Param)
{
}
public static void OnClientDisconnect(Socket Sender, object Param)
{
}
public static void OnClientReceive(Socket Sender, byte[] Param)
{
}






