I. Preface:
Microsoft's. NET Framework provides two namespaces for network programming: system. NET and system. net. sockets. By properly using the classes and methods, we can easily compile various network applications. Such network applications can be based on both stream sockets and datagram sockets. TCP is the most widely used protocol in stream socket-based communication. UDP is the most widely used protocol in datagram socket-based communication. Next I will focus on introducing it to you. net network programming class: DNS class, iphostentry class, ipendpoint class, and socket class, and a web page download server instance will be provided at the end to deepen the reader's understanding. net network programming.
Ii. network programming class introduction:
DNS class:
Provides domain name services to applications that use TCP/IP Internet services. Its resolve () method queries DNS servers to map user-friendly Domain Names (such as "www.google.com") to digital Internet addresses (such as 192.168.1.1 ). The resolve () method returns an iphostenty instance that contains a list of the addresses and aliases of the requested names. In most cases, you can use the first address returned in the Addresslist array.
The function prototype of the resolve () method is as follows:
Public static iphostentry resolve (string hostname );
The following code gets an IPaddress instance that contains the IP address of the server www.google.com:
Iphostentry iphostinfo = DNS. Resolve ("www.google.com "); IPaddress = iphostinfo. Addresslist [0];
However, in the DNS class, in addition to the resolve () method, you can also use the gethostbyaddress () method and gethostbyname () method to obtain the corresponding iphostentry instance. The function prototype is as follows:
Public static iphostentry gethostbyaddress (string IPaddress ); Public static iphostentry gethostbyname (string hostname );
The following code shows how to use the above two methods to obtain iphostentry instances that contain information about the server www.google.com:
Iphostentry hostinfo = DNS. gethostbyaddress ("192.168.1.1 "); Iphostentry hostinfo = DNS. gethostbyname ("www.google.com ");
When using the preceding methods, you may need to handle the following exceptions:
Socketexception exception: the operating system error occurs when the socket is accessed.
Argumentnullexception exception: the parameter is null.
Objectdisposedexception exception: the socket has been closed.
As mentioned above, I briefly introduced some methods and their usage in the DNS class, and listed some possible exceptions, next let's go to the iphostentry class closely related to the DNS class.
Iphostentry class:
This type of instance object contains the address information of the Internet host. All public static members of this type are secure for multi-threaded operations, but they are not guaranteed to be thread-safe for any instance members. The main attributes include Addresslist, aliases, and hostname.
The Addresslist attribute and the aliases attribute are used to obtain or set the list of IP addresses associated with the host and the list of aliases associated with the host. The Addresslist attribute value is an array of the IPaddress type, including the IP address resolved to the host name included in the aliases attribute; the aliases attribute value is a set of strings that contain the DNS name resolved to the IP address in the Addresslist attribute. The hostname attribute is easy to understand. It contains the main host name of the server, which can be understood simply by the name. If the DNS entry of the server defines additional aliases, you can use these aliases in the aliases attribute.
The following code lists the related aliases of the server www.google.com and the length of the IP address list, and lists all IP addresses:
Iphostentry iphost = DNS. Resolve ("www.google.com /"); String [] aliases = iphost. aliases; Console. writeline (aliases. Length );
IPaddress [] ADDR = iphost. Addresslist; Console. writeline (ADDR. Length ); For (INT I = 0; I <ADDR. length; I ++) { Console. writeline (ADDR [I]); }
After the iphostentry class is introduced, we can obtain the IP address and Alias List of the host to be connected. However, an important class-ipendpoint class is required to connect to the host.
Ipendpoint class:
In the Internet, TCP/IP uses a network address and a service port number to uniquely identify the device. The network address identifies a specific device on the network, and the port number identifies a specific service on the device to be connected. The combination of network addresses and service ports is called an endpoint. in the. NET Framework, the endpoint class indicates the endpoint. It provides an abstraction that represents network resources or services and marks network addresses and other information .. Net also defines the child of an endpoint for each supported address family. For an IP address family, this class is ipendpoint. The ipendpoint class contains the host and port information required by the application to connect to the service on the host. The ipendpoint class forms a connection point to the service by combining the Host IP address and port number of the service.
There are two useful constructors in the ipendpoint class:
Public ipendpoint (long, INT ); Public ipendpoint (IPaddress, INT );
They are used to initialize a new instance of the ipendpoint class with the specified address and port number. The attributes in this class include Address, addressfamily, and port. These attributes are relatively easy to understand and will not be described here. The following code shows how to get the end point of the server www.google.com:
Iphostentry iphost = DNS. Resolve ("www.google.com "); IPaddress [] ADDR = iphost. Addresslist; Ipendpoint Ep = new ipendpoint (ADDR [0], 80 );
In this way, we have learned some basic classes necessary to connect to the host. With this knowledge, we can use the following socket class to truly connect to and communicate with the host.
Socket class:
The socket class is a very important class contained in the system. net. Sockets namespace. A socket instance contains a local and a remote endpoint. As described above, the endpoint contains some information about the socket instance.
You need to know that the socket class supports two basic modes: synchronous and asynchronous. The difference is that in synchronous mode, the call to the function that executes network operations (such as send and receive) will not return the control to the caller until the operation is complete. In asynchronous mode, these calls return immediately.
Next we will focus on socket programming in synchronization mode. First, the basic process of socket programming in synchronization mode is as follows:
1. Create a socket instance object.
2. Connect the above instance object to a specific endpoint ).
3. After the connection is complete, you can communicate with the server: receive and send information.
4. After the communication is completed, use the shutdown () method to disable the socket.
5. Use the close () method to close the socket.
After learning about the above basic process, we can further implement the connection and communication. Before using it, you must first create an instance of the socket object, which can be achieved through the socket class constructor:
Public socket (addressfamily, sockettype Sockettype, protocoltype );
The addressfamily parameter specifies the addressing scheme used by the socket, such as addressfamily. internetwork indicates the IP address of IP version 4. The sockettype parameter specifies the socket type, such as sockettype. stream indicates that the connection is based on the stream socket, while sockettype. dgram indicates that the connection is based on the datagram socket. The protocoltype parameter specifies the protocol used by the socket. For example, protocoltype. TCP indicates that the connection protocol uses the TCP protocol, while protocol. UDP indicates that the connection protocol uses the UDP protocol.
After a socket instance is created, we can connect to it through a remote host endpoint. The CONNECT () method is used:
Public connect (endpoint EP );
This method can only be used on the client. After the connection, we can use the connected attribute of the socket to verify whether the connection is successful. If the returned value is true, the connection is successful. Otherwise, the connection fails. The following code shows how to create a socket instance and connect it through the endpoint:
Iphostentry iphost = DNS. Resolve ("http://www.google.com /"); String [] aliases = iphost. aliases; IPaddress [] ADDR = iphost. Addresslist; Endpoint Ep = new ipendpoint (ADDR [0], 80 );
Socket sock = newsocket (addressfamily. InterNetwork, Sockettype. Stream, protocoltype. TCP ); Sock. Connect (EP ); If (sock. Connected) Console. writeline ("OK ");
Once the connection is successful, we can use the send () and receive () methods for communication.
The function prototype of the send () method is as follows:
Public int send (byte [] buffer, int size, socketflags flags );
The buffer parameter contains the data to be sent. The size parameter indicates the size of the data to be sent. The flags parameter can be of the following values: socketflags. none, socketflags. dontroute, socketflags. outofbnd.
This method returns a value of the system. int32 type, which indicates the size of the sent data. At the same time, this method also has the following functions that have been overloaded:
Public int send (byte [] buffer ); Public int send (byte [] buffer, socketflags flags ); Public int send (byte [] buffer, int offset, int size, Socketflags flags );
After introducing the send () method, the following is the receive () method. Its function prototype is as follows:
Public int receive (byte [] buffer, int size, socketflags flags );
The parameters are similar to those of the send () method.
Similarly, this method has the following functions that have been overloaded:
Public int receive (byte [] buffer ); Public int receive (byte [] buffer, socketflags flags ); Public int receive (byte [] buffer, int offset, int size, Socketflags flags );
After the communication is complete, we disable the socket through the shutdown () method. The function prototype is as follows:
Public void Shutdown (socketshutdown how );
The parameter "how" indicates the disabled type, soketshutdown. send indicates that the socket used for sending is closed; soketshutdown. receive indicates that the socket used for receiving is disabled, while soketshutdown. both indicates that the socket for sending and receiving is closed at the same time.
It should be noted that the shutdown () method must be called before the close () method is called to ensure that all suspended data has been sent or received before the socket is closed. Once Shutdown () is called, the close () method is called to close the socket. The function prototype is as follows:
Public void close ();
This method forces a socket connection to close and release all managed and unmanaged resources. This method actually calls the method dispose () internally. This function is of a protected type. Its prototype is as follows:
Protected virtual void dispose (bool disposing );
Where, the disposing parameter is true or false. If it is true, both managed and unmanaged resources are released. If it is false, only unmanaged resources are released. Because the parameter when the close () method calls the dispose () method is true, it releases all managed and unmanaged resources.
In this way, the process from creating a socket to closing the connection to the communication is complete. Although the entire process is complex, it is quite easy to program the socket in the SDK or other environments. |