Microsoft. net Framework provides applications with hierarchical, scalable, and governed network services to access the Internet. Its namespace is System. net and System. net. sockets contains a variety of classes to develop a variety of network applications .. . Net class uses a layered structure that allows applications to access the network at different control levels. developers can choose to compile programs at different levels as needed, these levels cover almost all the needs of the Internet-from socket sockets to common requests/responses. More importantly, this layer can be expanded to meet the needs of continuous Internet expansion.
Aside from the layer-7 architecture of the ISO/OSI model, we can look at the logic layer of the TCP/IP model ,. net class can be considered to contain three layers: Request/response layer, application protocol layer, and transmission layer. WebReqeust and WebResponse represent the request/response layer. Classes supporting Http, Tcp, and Udp constitute the application protocol layer, while the Socket class is in the transmission layer. It can be illustrated as follows:
It can be seen that the transport layer is at the bottom of this structure. When the application protocol layer and request/response layer above it cannot meet the special needs of the application, you need to use this layer for Socket programming.
In. Net, the System. Net. Sockets namespace provides a managed implementation of the Windows Sockets (Winsock) interface for developers who need to strictly control network access. System. all other network protocol classes in the. Net namespace are built on the Socket implementation. For example, TCPClient, TCPListener, and UDPClient encapsulate detailed information about TCP and UDP connections created to the Internet; the NetworkStream class provides basic data streams for network access. Many common Internet services can see Socket traces, such as Telnet, Http, Email, and Echo, despite the different definitions of the communication Protocol, the basic transmission of these services uses sockets.
In fact, the Socket can be considered as a data channel like a Stream. This channel is set up between the application end (client) and the remote server end, and then reads (receives) data) and write (send) for this channel.
It can be seen that after a Socket object is created on the application or server, you can use the Send/SentTo method to Send data to the connected Socket, alternatively, use the Receive/ReceiveFrom method to Receive data from the connected Socket;
For Socket programming, the Socket class of the. NET Framework is the managed code version of the Socket service provided by the Winsock32 API. A large number of methods are provided for network programming. In most cases, the Socket class method only sends data to their local Win32 copies and handles any necessary security checks. If you are familiar with Winsock API functions, it will be very easy to write network programs using the Socket class. Of course, if you have never been in touch with it, it will not be too difficult. Follow the instructions below, you will find that there are rules to develop windows network applications using the Socket class, which follow roughly the same steps in most cases.
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 addressFamily, SocketType socketType, ProtocolType protocolType );
The addressFamily parameter specifies the addressing scheme used by the Socket, The socketType parameter specifies the Socket type, and the protocolType parameter specifies the protocol used by the Socket.
The following example creates a Socket that can be used for communication over TCP/IP-based networks (such as the Internet.
Socket s = new Socket (AddressFamily. InterNetwork, SocketType. Stream, ProtocolType. Tcp );
To use UDP instead of TCP, you need to change the protocol type, as shown in the following example:
Socket s = new Socket (AddressFamily. InterNetwork, SocketType. Dgram, ProtocolType. Udp );
Once a Socket is created on the client, you can Connect to the specified server through the Connect method and Send data to the remote server through the Send/SendTo method, then, you can use Receive/ReceiveFrom to Receive data from the server. on the server side, you need to Bind the specified interface using the Bind method to associate the Socket with a local endpoint, the Listen method is used to Listen for requests on this interface. When listening for a connection to the user end, the Accept is called to complete the connection operation, and a new Socket is created to process incoming connection requests. After using the Socket, remember to use the Shutdown method to disable the Socket and use the Close method to Close the Socket. The methods/functions used in this process include:
Socket. Connect Method: establish a connection to a remote device
Public void Connect (EndPoint remoteEP) (with overload method)
Socket. Send method: sends data to the connected Socket starting from the indicated position in the data.
Public int Send (byte [], int, SocketFlags); (there are overload methods)
The Socket. SendTo method sends data to a specific endpoint.
Public int SendTo (byte [], EndPoint); (there are overload methods)
Socket. Receive method: receives data from the connected Socket to a specific location in the receiving buffer.
Public int Receive (byte [], int, SocketFlags );
Socket. ReceiveFrom method: receives data from a specific location in the data buffer and stores the endpoint.
Public int ReceiveFrom (byte [], int, SocketFlags, ref EndPoint );
Socket. Bind method: Associate the Socket with a local endpoint:
Public void Bind (EndPoint localEP );
Socket. Listen method: place the Socket in the listening state.
Public void Listen (int backlog );
Socket. Accept method: Create a new Socket to process incoming connection requests.
Public Socket Accept ();
Socket. Shutdown method: Disable sending and receiving on a Socket
Public void Shutdown (SocketShutdown how );
Socket. Close method: Force Socket connection to Close
Public void Close ();
As you can see, the preceding methods contain EndPoint parameters. On 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.
When using the IPEndPoint class, it inevitably involves the computer ip address. There are two types of. Net IP address instances:
IPAddress: The IPAddress class contains the IP address of the computer on the IP network. The Parse method can convert an IP address string to an IPAddress instance. The following statement creates an IPAddress instance:
IPAddress myIP = IPAddress. Parse ("192.168.1.2 ");
Dns: 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 "host.contoso.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 following code obtains an IPAddress instance that contains the IP address of host.contoso.com.
IPHostEntry ipHostInfo = Dns. Resolve ("host.contoso.com ");
IPAddress ipAddress = ipHostInfo. AddressList [0];
You can also use the GetHostName method to obtain the IPHostEntry instance:
IPHosntEntry hostInfo = Dns. GetHostByName ("host.contoso.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.
After learning the above knowledge, the following code combines the IP address and port number of the server host (host.contoso.com) to create a remote endpoint for the connection:
IPEndPoint ipe = new IPEndPoint (ipAddress, 11000 );
After the address of the remote device is determined and the port used for connection is selected, the application can try to establish a connection with the remote device. The following example uses an existing IPEndPoint instance to connect to a remote device and capture Possible exceptions:
Try {
S. Connect (ipe); // try to Connect
}
// An exception occurred when the processing parameter is null.
Catch (ArgumentNullException AE ){
Console. WriteLine ("ArgumentNullException: {0}", AE. ToString ());
}
// Handle operating system exceptions
Catch (SocketException se ){
Console. WriteLine ("SocketException: {0}", se. ToString ());
}
Catch (Exception e ){
Console. WriteLine ("Unexpected exception: {0}", e. ToString ());
}
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.
In addition, in many cases, Socket programming is implemented on the client and server based on different situations, and the application program is compiled on the client to send requests to the specified port on the server, at the same time, the preparation of the server application to process the request has been mentioned in the above description; of course, not all Socket programming requires you to strictly write these two programs; depending on the application situation, you can construct a request string on the client. The corresponding port of the server captures the request and submits it to its public service program for processing. The string in the following example sends a page request to the remote host:
String Get = "GET/HTTP/1.1/r/nHost:" + server + "/r/nConnection: Close/r/n ";
After the specified port of the remote host receives this request, it can use its public service program for processing without the need to compile server applications separately.
Using the knowledge of using Visual C # For Socket network program development described above, the program section below fully implements the Web page download function. You only need to enter the remote host name (Dns host name or IP address in four-part notation separated by dots) and the pre-saved local file name on the form, the remote host page can be obtained and saved in the specified file on the local machine by using port 80 that provides the Http service. If the format is .htm, you can open the page in an Internet browser. Add code as appropriate, and you can even implement a simple browser program.
The main source code for implementing this function is as follows:
// "Start" button event
Private void button#click (object sender, System. EventArgs e ){
// Obtain the pre-saved file name
String fileName = textBox3.Text. Trim ();
// Remote host
String hostName = textBox1.Text. Trim ();
// Port
Int port = Int32.Parse (textBox2.Text. Trim ());
// Obtain host information
IPHostEntry ipInfo = Dns. GetHostByName (hostName );
// Obtain IPAddress []
IPAddress [] ipAddr = ipInfo. AddressList;
// Obtain the ip address
IPAddress ip = ipAddr [0];
// Combine remote endpoints
IPEndPoint hostEP = new IPEndPoint (ip, port );
// Create a Socket instance
Socket socket = new Socket (AddressFamily. InterNetwork, SocketType. Stream, ProtocolType. Tcp );
Try
{
// Try to connect
Socket. Connect (hostEP );
}
Catch (Exception se)
{
MessageBox. Show ("connection error" + se. Message, "prompt Message
, MessageBoxButtons. RetryCancel, MessageBoxIcon. Information );
}
// Request content string sent to the remote host
String sendStr = "GET/HTTP/1.1/r/nHost:" + hostName +
"/R/nConnection: Close/r/n ";
// Create a bytes byte array to convert the sending string
Byte [] bytesSendStr = new byte [1, 1024];
// Convert the sent content string to a byte array
BytesSendStr = Encoding. ASCII. GetBytes (sendStr );
Try
{
// Send a request to the host
Socket. Send (bytesSendStr, bytesSendStr. Length, 0 );
}
Catch (Exception ce)
{
MessageBox. Show ("sending error:" + ce. Message, "prompt Message
, MessageBoxButtons. RetryCancel, MessageBoxIcon. Information );
}
// Declare the string that receives the returned content
String recvStr = "";
// Declare a byte array. The length of data received at a time is 1024 bytes.
Byte [] recvBytes = new byte [1, 1024];
// Returns the actual number of bytes of received content.
Int bytes = 0;
// Read data cyclically until all data is received
While (true)
{
Bytes = socket. Receive (recvBytes, recvBytes. Length, 0 );
// Exit the loop after reading.
If (bytes <= 0)
Break;
// Convert the number of bytes read to a string
RecvStr + = Encoding. ASCII. GetString (recvBytes, 0, bytes );
}
// Convert the read string to a byte array
Byte [] content = Encoding. ASCII. GetBytes (recvStr );
Try
{
// Create a file stream object instance
FileStream fs = new FileStream (fileName, FileMode. OpenOrCreate, FileAccess. ReadWrite );
// Write a file
Fs. Write (content, 0, content. Length );
}
Catch (Exception fe)
{
MessageBox. Show ("file creation/writing error:" + fe. Message, "prompt Message", MessageBoxButtons. RetryCancel, MessageBoxIcon. Information );
}
// Disable Socket
Socket. Shutdown (SocketShutdown. Both );
// Close the Socket
Socket. Close ();
}
}
From caoruyi15's column