Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Sockets in C#

0.00/5 (No votes)
29 Oct 2003 1  
Introduction to using Sockets in C#.

Introduction

C# is a powerful tool for network programming. In socket programming, there are several steps - like client side, server side, blocking or synchronous, non-blocking or asynchronous etc. The part 1 of this article will start with the client side blocking socket. Later on, the second part will show you how to create server side and non-blocking.

What are Sockets?

A socket is like a handle to a file, which is used to open the path to communicate with another machine. It resembles the file IO, as does the serial communication. Using socket programming, we can have communication between two applications. The applications are typically on different computers or in the same computer. For the two applications to talk to each either on the same or different computers, one application is generally a server that keeps listening to the incoming requests and the other application acts as a client and makes the connection to the server application.

The server application can either accept or reject the connection. If the server accepts the connection, a dialog can begin between the client and the server. Once the client is done with whatever it needs to do, it can close the connection with the server. Connections are expensive in the sense that servers allow only finite connections to occur. During the time client has an active connection, it can send the data to the server and/or receive the data.

When the client or server is trying to make a connection, then we have to be careful. When either side (client or server) sends data, the other side is supposed to read the data. But how will the other side know when data has arrived. There are two options - either the application needs to poll for the data at regular intervals or there needs to be some sort of mechanism that would enable the application to get notifications and application can read the data at that time. Windows is an event driven system and the notification system seems an obvious and best choice and it in fact is.

The two applications that need to communicate with each other need to make a connection first. If each machine wants to make a connection they have to identify themselves. Using the IP of the machine, they are identified. IP address is nothing but the eight octal numbers, like 107.108.1.179. First two octal shows the network ID and third and fourth octal shows the host ID.

Sockets in C#.

System.Net.Sockets namespace contains the required classes. A socket program mostly consists of two parts. They are:

  • Server
  • Client

In the client side, the client is started to establish the connection with the server. The code is shown below:

Project ("{EFDR3456}") = "SocketClientProject", 
   "SocketClientProject.csproj", "{EFDR3456 }" EndProject 
Global 
GlobalSection(SolutionConfiguration) = preSolution 
ConfigName.0 = Debug 
ConfigName.1 = Release 
EndGlobalSection 
GlobalSection(ProjectDependencies) = postSolution 
EndGlobalSection 
GlobalSection(ProjectConfiguration) = postSolution 
{EFDR3456 }.Debug.ActiveCfg = Debug|.NET 
{EFDR3456 }.Debug.Build.0 = Debug|.NET 
{EFDR3456 }.Release.ActiveCfg = Release|.NET 
{EFDR3456 }.Release.Build.0 = Release|.NET 
EndGlobalSection 
GlobalSection(ExtensibilityGlobals) = postSolution 
EndGlobalSection 
GlobalSection(ExtensibilityAddIns) = postSolution 
EndGlobalSection 
EndGlobaln

If we run the program in VS.NET then we get a window that asks the host IP and port settings. If you connect, then it asks for the data you want to send. After you type in the data, the data bytes are transmitted. It has the option to mention the port. It is a 4 digit number which shows the port to to listen, for the client. And in the client side, you can block the date by pressing Rx.

After specifying these parameters, we need to connect to the server. So pressing Connect will connect to the server and to close the connection press Close. To send some data to the server type some data in the field near the button named Tx and if you press Rx, the application will block unless there is some data to read.

With this info, lets now try to check the code behind this:

Socket programming in .NET is made possible by Socket class present inside the System.Net.Sockets namespace. Socket class has several methods and properties and a constructor. The first step is to create an object of this class. Since there is only one constructor, we have no choice but to use it.

Here is how to create the socket:

m_socListener = new Socket 
(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.IP);

The first parameter is the address family which we will use: interNetwork. Other options include Banyan Net Bios etc.

Address family is an enum defined in Sockets namespace. Next we need to specify socket type: and we would use reliable two way connection-based sockets (stream) instead of un-reliable connectionless sockets (datagrams). So we obviously specify stream as the socket type and finally we are using TCP/IP, so we would specify protocol type as TCP. Once we have created a socket, we need to make a connection to the server since we are using connection-based communication. To connect to the remote computer, we need to know the IP Address and port at which to connect.

In .NET, there is a class under System.Net namespace called IPEndPoint, which represents a network computer as an IP address and a port number. The IPEndPoint has two constructors - one that takes an IP address and port number and one that takes long and port number. Since we have computer IP address, we would use the former:

public IPEndPoint(System.Net.IPAddress address, int port);

In this, it takes an IPAddress object. If you examine the IPAddress class, you will see that it has a static method called Parse that returns the IP address, given a string and second parameter will be the port number. Once we have the endpoint ready, we can use Connect method of Socket class to connect to the end point (remote server computer).

Here is the code:

System.Net.IPAddress ipAdd = System.Net.IPAddress.Parse("107.108.1.179"); 
System.Net.IPEndPoint remoteEP = new IPEndPoint (iAdd,5002); 
m_socClient.Connect (remoteEP);

These three lines of code will make a connection to the remote host running on the computer with IP 107.108.1.179 and listening at port 5002. If the server is running and started (listening), the connection will succeed. If however the server is not running, an exception called SocketException will be thrown. If you catch the exception and check the Message property of the exception, in this case, you will see the following text:

"No connection could be made because the target machine actively refused it."

Similarly if you already have made a connection and the server somehow dies, you will get the following exception if you try to send data: "An existing connection was forcibly closed by the remote host". Assuming that the connection is made, you can send data to the other side using the Send method of the Socket class.

Send method has several overloads. All of them take a byte array. For example, if you want to send "I am here" to host, you can use the following call:

try 
{ 
  String szData = "I am here"; 
  byte[] byData = System.Text.Encoding.ASCII.GetBytes(szData); 
  m_socClient.Send(byData); 
} 
catch (SocketException se) 
{ 
  MessageBox.Show ( se.Message ); 
}

Note that the Send method is blocking. What it means is, the call will block till the data has been sent or an exception has been thrown. There is a non-blocking version of Send which we will discuss in the next part of this article.

Similar to Send, there is a Receive method on the Socket class. You can receive data using the following call:

byte [] buffer = new byte[1024];
int iRx = m_socClient.Receive (buffer);

The Receive method again is blocking. It means that if there is no data available, the call will block until some data arrives or an exception is thrown.

Non-blocking version of Receive method is more useful than the non-blocking version of Send, because if we opt for block Receive, we are effectively doing polling. There are no events about data arrival. This model does not work well for serious applications. But all that is the subject of our next part of this article. For now, we will settle with the blocking version.

In order to use the source code and application, you would need to run the server first. Then you run your client code. Your sever code will be waiting for the client connection.

Normally system uses the lower ports. It means it uses the ports below 3000. So the user can open the ports above that.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here