Microsoft .NET Compact Framework Kick Start
| The central class for socket programming with the .NET Compact Framework is the System.Net.Sockets.Socket class. The procedure for getting a Socket class connected to a remote computer depends on whether the socket connects as the host or as the client. Once the Socket is connected to a remote computer, however, the processes for reading and writing are exactly the same. Making a Connection as a Client
To successfully make a connection as a client, we must first understand the System.Net.EndPoint class. The EndPoint holds the information about where to connect to the IPv4 address of the host and the desired port. To set up a valid EndPoint and use it to connect a socket to a host, follow these steps:
The following code sample illustrates the three steps just described:
C# try { Socket l_Socket = new Socket(Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); l_Socket.Connect(l_EndPoint); if (l_Socket.Connected){ // l_Socket is now ready to send and receive data } } catch (SocketException e) { /* do something about it */ } VB Dim l_Socket As System.Net.Sockets.Socket Try l_Socket = New System.Net.Sockets.Socket( System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp) l_Socket.Connect(l_EndPoint) If (l_Socket.Connected) Then ' l_Socket is now ready to send and receive data End If Catch e as System.Net.Sockets.SocketException ' Do something about the problem End Try Receiving a Connection as a Host
You can acquire a socket connection to a remote computer by acting as the host. When a device acts as a host, it waits to receive a connection from another client. For your device to receive a connection as a host, you must set up a socket to listen on a specific port until someone sends a request to connect with your device. Follow these steps to listen on a socket for clients to connect to you:
The following code sample illustrates the three steps just described:
C# m_listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); m_listenSocket.Bind(new IPEndPoint(IPAddress.Any, 8758)); m_listenSocket.Listen((int)SocketOptionName.MaxConnections); m_connectedSocket = m_listenSocket.Accept(); if (m_connectedSocket != null) { if (m_connectedSocket.Connected) { // Someone has connected to us. } } VB m_listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) m_listenSocket.Bind(new IPEndPoint(IPAddress.Any, 8758)) m_listenSocket.Listen((int)SocketOptionName.MaxConnections) m_connectedSocket = m_listenSocket.Accept() If (m_connectedSocket != null) Then If (m_connectedSocket.Connected) Then ' Someone has connected to us. End If End If Reading and Writing with a Connected Socket
Once a socket is connected to a remote computer, it can be used to send and receive data. The simplest way to do this is to call Socket.Send() to send data and Socket.Receive() to receive data. Writing Data to a Socket with Socket.Send
Socket.Send() has four overloads, each offering a different level of control over what is sent: Send(Byte[] buffer) This overload sends everything inside the buffer byte array. Send(Byte[] buffer, SocketFlags socketFlags) This overload sends everything in buffer with special control over how the data is routed. Send(Byte[] buffer, Int32 size, SocketFlags socketFlags) This overload sends everything in the buffer up to size bytes. If you want to send only part of a buffer, then you can specify SocketFlags.None to use the default routing behavior. For example, to send the first 16 bytes out of a byte array, you could use l_Socket.Send(l_buffer, 16, SocketFlags.None) . Send(Byte[] buffer, Int32 offset Int32 size, SocketFlags socketFlags) This overload is like the previous one except you can specify which index within the byte array to start from. For example, to send bytes 3 through 7 of a byte array, you could use the following:
C# l_Socket.Send(l_buffer, 2, 6, SocketFlags.None); VB l_Socket.Send(l_buffer, 3, 7, SocketFlags.None) The Send method returns the number of bytes successfully sent. The problem with the Send() method is that it seems like a lot of work to convert everything you want to send into an array of bytes just to send it through a socket. Fortunately, the .NET Compact Framework supports two very useful classes, System.Text.Encoding and System.Convert , that make it easy to convert fundamental data types into byte arrays that can be sent through the socket. To send an entire object through a socket, you must serialize the object, as discussed in the section "Serializing Objects for Transmission through a Socket." The easiest way to understand how to use the Encoding and Convert classes is to look at examples. The following examples assume that a socket named l_Socket exists and is connected:
C#
Reading Data from a Socket with Socket.Receive
Receive data from a socket through the Socket.Receive method. Receive has four overloads, similar to the overloads for Socket.Send . Each of the following overloads returns the number of bytes successfully read: Receive (Byte[] buffer ) This overload receives data into buffer. Receive (Byte[] buffer, SocketFlags socketFlags) This overload receives data into buffer by using the flags to specify controlling how data is routed. Receive (Byte[] buffer, Int32 size, SocketFlags socketFlags) This overload receives up to size bytes of data into the buffer. Even if more data is available, it is ignored. You can retrieve the remaining data by calling Receive again. If you want to receive only a specified number of bytes but you have no restrictions on the routing behavior, then you can specify SocketFlags.None to use the default routing behavior. For example, to receive only the first the 16 bytes of the available data, use l_Socket.Receive(l_buffer, 16, SocketFlags.None) Receive (Byte[] buffer, Int32 offset Int32 size, SocketFlags socketFlags) This overload is like the previous one except you can specify which index within the byte array to use to start writing data into the array. For example, to receive up to 7 bytes of data into the buffer starting at position 3 in the buffer, use this code:
C# l_Socket.Receive(l_buffer, 2, 6, SocketFlags.None); VB l_Socket.Receive(l_buffer, 3, 7, SocketFlags.None)
Just as there are techniques for converting the data to send out of a socket into byte arrays, there are simple techniques for converting byte arrays into fundamental data types. As before, the Encoding and Convert classes provide the means for conversion, and we will look at examples. These examples assume the data has been received into a Byte array named l_Buffer :
C#
Table 5.1 lists all of the conversions supported by the Convert class on the .NET Compact Framework.
Table 5.1. The Convert Class on the .NET Compact Framework
Sample Application: Remote Hello
This sample application pulls together the three most basic actions developers do with sockets: connect to a host, listen for a client, and exchange data. The application is split into two separate programs, a server and a client. The server always listens on port 8758 and uses DNS lookup to show what its IP address is. The client has a space for entering an IP address and a button to connect to the remote host. When a connection is made, the server sends a string that says "Hello!" and the client displays it. Then the client closes the connection, and the host starts listening again. The C# version of the Remote Hello client is in the directory SampleApplications\ Chapter5\RemoteHelloClient_CSharp , and the VB version is in SampleApplications\ Chapter5\RemoteHelloClient_VB . The server is in the folders RemoteHelloServer_CSharp and RemoteHelloServer_VB . Observe that the code accesses the same classes from the .NET Compact Framework regardless of which language is used. Also, because sockets are platform agnostic , you can connect to the Visual Basic host with the C# client and vice versa. |