Chapter 9: Server Sockets


In the previous chapter, the Socket class was introduced, as well as the basic concepts of setting up a socket and establishing client connections when using a connection-oriented protocol such as TCP. This chapter details how to create a server, or listening socket, with the Socket class that accepts one or more client connections. The previous chapter covered the TcpListener class and illustrated how this process basically works.

This chapter is divided into three sections: creating server sockets, socket security, and asynchronous socket operations. The first part discusses how to create a server socket using the Socket class and how to accept a client connection. The second part covers socket security, including how to prevent malicious processes from creating sockets that are bound to the same interface and port as an existing server socket as well as controlling what clients can connect to the server socket. The final section discusses how to use asynchronous operations on the Socket class, which is the building block for high-performance network applications.

Server Creation

As mentioned earlier, this chapter uses the term server socket to refer to an instance of the Socket class for a connection-oriented protocol used to accept incoming client connections. Once a server is created and set to listen for incoming connections, it can accept only connections ”it can t be used as a client socket. Server sockets have two parts : creating a listening socket and accepting client connections. The next two sections discuss these concepts in detail.

Listening Sockets

The steps for creating a server socket are similar to client sockets: the socket is created and must be bound followed by calling the Listen method. A server socket must call the Bind method to indicate which interface the server will listen on. In general, the server can listen on one specific interface or on all interfaces. For example, if a TCP/IPv4 server is being created on a machine with two network interfaces with the addresses 10.10.10.1 and 192.168.1.1, the server can be bound specifically to one of these addresses, such as the 10.10.10.1 address and port 5150. If a client TCP connection request is received on the 192.168.1.1 interface and port 5150, it will be rejected because no server is listening on that address and port. If the server wants to receive connections across all interfaces, it should bind to the wildcard address for the address family being used, which for IPv4 is IPAddress.Any (equal to 0.0.0.0).

Once the socket is bound, the call to Listen indicates that the socket will be a server socket that accepts client connections received on the interface and port the socket was bound to. Note that Listen can be called only on sockets for protocols that are connection-oriented (such as TCP). If Listen is called on a non-connection-oriented protocol, a SocketException is generated. Also, if Listen is called on a Socket object that s not bound, a SocketException is thrown.

The netstat.exe command-line utility can be used to display TCP and UDP sockets and what addresses and ports they are bound to, as well as indicate the state of the socket (connected, listening, and so on). The following code is the output of netstat.exe -aon . On Microsoft Windows XP and later, the -o switch will include the process ID of the process owning the given socket entry.

 ActiveConnections ProtoLocalAddressForeignAddressStatePID TCP0.0.0.0:1350.0.0.0:0LISTENING940 TCP0.0.0.0:4450.0.0.0:0LISTENING4 TCP4.65.4.128:3295207.46.196.119:80ESTABLISHED620 TCP4.65.4.128:3302131.107.39.8:1723ESTABLISHED4 TCP4.65.4.128:114240.0.0.0:0LISTENING3328 TCP172.30.45.183:3312157.54.7.23:80ESTABLISHED620 TCP[::]:135[::]:0LISTENING940 TCP[::]:1025[::]:0LISTENING988 TCP[::]:42510[::]:0LISTENING1572 UDP0.0.0.0:445*:*4 UDP0.0.0.0:500*:*748 

The following code illustrates creating a TCP/IPv4 server socket listening on the wildcard address:

C#

 IPEndPointlistenEndPoint=newIPEndPoint(IPAddress.Any,5150); SockettcpServer=newSocket(listenEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); tcpServer.Bind(listenEndPoint); tcpServer.Listen(int.MaxValue); 

Visual Basic .NET

 DimlistenEndPointAsIPEndPoint=NewIPEndPoint(IPAddress.Any,5150) DimtcpServerAsSocket=NewSocket(_ listenEndPoint.AddressFamily,_ SocketType.Stream,_ ProtocolType.Tcp_) tcpServer.Bind(listenEndPoint) tcpServer.Listen(Integer.MaxValue) 

The only parameter to Listen is known as the backlog , which indicates how many client TCP connections can be queued on the listening socket at any given time. A server socket can dequeue a client connection by calling the Accept method or by using the asynchronous BeginAccept . If the backlog is set to 1, it means that if the server does not accept the client connection, only a single TCP client connection will be accepted. Any subsequent connection requests will be refused by the networking stack. Once the server accepts the connection, the pending connection is removed from the queue and another connection can be queued. The client that s refused will receive a SocketException on its connection request.

In the previous code sample, the backlog is set to the maximum integer value, but note that the underlying network stack will reset this value to its internal maximum value. Currently, on Windows Server, the maximum is 200. On professional and home versions of Windows, the maximum backlog is 5. If a server is expected to handle a large number of incoming connections, the backlog should be set to the maximum.

Note  

On Windows Server 2003 SP1 and later, the home and client versions will have the same backlog limit as server versions.

Accepting Client Connections

After the server socket has been established, the server can make a blocking call to Accept to accept a client connection. If a client connection is pending, it s dequeued from the listen backlog, and if no connection is pending, the Accept call blocks until a client connection request is received. The asynchronous call to accept a connection is BeginAccept and will be covered in detail in the Asynchronous Accept section later in this chapter.

The Accept method takes no arguments and simply returns a Socket object that references the client connection. All data transfers then occur on the Socket object returned. The RemoteEndPoint property of the returned Socket object contains the address information of the connecting client.

The following code continues the previous example. In this code, once the listening socket is established, the server sits in an infinite loop waiting for a client connection. Once a client connection is accepted, data is received from the client until the connection is closed, at which point the server will handle the next client connection.

C#

 SockettcpClient; byte[]receiveBuffer=newbyte[4096]; while(true) { try { tcpClient=tcpServer.Accept(); Console.WriteLine("Acceptedconnectionfrom:{0}", tcpClient.RemoteEndPoint.ToString()); try { while(true) { intrc=tcpClient.Receive(receiveBuffer); if(rc==0) break; } } catch(SocketExceptionerr) { Console.WriteLine("Erroroccurredonacceptedsocket:{0}", err.Message); } finally { tcpClient.Close(); } } catch(SocketExceptionerr) { Console.WriteLine("Acceptfailed:{0}",err.Message); } } 

Visual Basic .NET

 DimtcpClientAsSocket DimreceiveBuffer(4096)AsByte DimrcAsInteger While(True) Try tcpClient=tcpServer.Accept() Console.WriteLine(Acceptedconnectionfrom:{0}",_ tcpClient.RemoteEndPoint.ToString()) Try While(True) rc=tcpClient.Receive(receiveBuffer) If(rc=0)Then ExitWhile EndIf EndWhile CatcherrAsSocketException Console.WriteLine(Erroroccurredonacceptedsocket:{0}",_ err.Message) Finally tcpClient.Close() EndTry CatcherrAsSocketException Console.WriteLine(Acceptfailed:{0}",err.Message) EndTry EndWhile 

Take a look at the SimpleSocket sample in Chapter 8 for an example on setting up a blocking TCP server.

Closing the Server

When a server no longer wants to accept client connections, it simply needs to call the Close method on the listening socket. Any queued client connection requests that have not been accepted with a blocking or an asynchronous accept will be reset. All client connections already accepted will not be affected when the server socket closes because each client is its own network connection that will not be closed until the Close method is called on its Socket object.




Network Programming for the Microsoft. NET Framework
Network Programming for the MicrosoftВ® .NET Framework (Pro-Developer)
ISBN: 073561959X
EAN: 2147483647
Year: 2003
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net