C #2.0 Socket socket programming example
Author: knife and light dance
First, explain the network communication using the socket interface in principle. Here we use the most common C/S mode as an example. First, the server has a process (or multiple processes) wait for the customer to connect to the specified port, and the service program waits for the customer's connection information. Once connected, the data can be transmitted according to the designed data exchange method and format. The client sends a connection request to the server whenever necessary. For ease of understanding, some calls and their general functions are mentioned here. After a socket call is used, only one socket descriptor can be used. At this time, communication is not allowed, and other calls are required, to complete the information used in the structure indicated by the socket.
When the TCP protocol is used, the server-side process first uses the SOCKET call to obtain a descriptor, and then uses the bind Call to connect a name to the socket descriptor, for an internet domain, the Internet address is associated with a socket. Then, the server uses the listen call to specify the length of the queue waiting for service requests. Then you can use accept to call and wait for the client to initiate a connection. Generally, it is to block and wait for the connection. Once a client sends a connection, accept returns the client's address information and a new socket descriptor, this descriptor has the same features as the original socket, and the server can use this new socket for read/write operations. Generally, the server may create a new process after the Accept return to communicate with the customer, and the parent process then waits for another connection at the Accept call. Client processes generally use socket to obtain a socket descriptor, and then use connect to initiate a connection to the specified port on the specified server. Once the connection is successful, it indicates that a connection has been established with the server. Then, you can perform read and write operations through the socket descriptor.
. Netframework provides the system. net. Socket namespace for socket communication. The namespace contains the following important classes:
· The socket class is a low-level class used internally to manage connections, webrequest, tcpclient, and udpclient.
· The networkstream class is derived from stream, which indicates data streams from the network.
· Tcpclient class allows you to create and use TCP connections
· Tcplistener class allows listening for incoming TCP connection requests
· Udpclient class is used to create connections for UDP clients (UDP is another TCP protocol, but it is not widely used and is mainly used for local networks)
Next we will look at a socket-based dual-machine communication code C # version
First, create an instance of the socket object, which can be achieved through the socket class constructor:
Public socket (addressfamily, sockettype, 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 temp = 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 temp = 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 (you can bind the port before the connect method, that is, initiate a connection with the specified port, if you do not bind the port number beforehand, the system will randomly bind a port number between 1024 and 5000 by default), send data to the remote server through the send method, and then receive data from the server through the receive; on the server side, you need to bind the specified interface using the bind method to associate the socket with a local endpoint and listen for requests on the interface using the listen method, when listening for connections to the user end, call accept to complete the connection operation and create a new socket to process incoming connection requests. After using the socket, use the close method to close the socket.
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, the computer ip address is inevitably involved. There are two types of IP address instances available in the system. Net namespace:
· IPaddress class: 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.0.1 "); |
You need to know that the socket class supports two basic modes: synchronous and asynchronous. The difference is that in synchronization mode, functions that perform network operations (such as send and receive) are transmitted by block) the control is returned to the caller until all content transfer operations are completed. In asynchronous mode, the message is transmitted by bit. You must specify the start and end of the message. The synchronization mode is the most commonly used mode, and the example here also uses the synchronization mode.
The following is a complete example. The client sends a test string to the server. The server receives and displays the string and returns a successful response to the client.
// Client Using system; Using system. text; Using system. IO; Using system. net; Using system. net. Sockets; Namespace socketsample { Class class1 { Static void main () { Try { Int Port = 2000; String host = "127.0.0.1 "; IPaddress IP = IPaddress. parse (host ); Ipendpoint IPE = new ipendpoint (IP, Port); // converts the IP address and port to an ipendpoint instance. Socket c = new socket (addressfamily. InterNetwork, sockettype. Stream, protocoltype. TCP); // create a socket Console. writeline ("conneting ..."); C. Connect (IPE); // connect to the server String sendstr = "Hello! This is a socket test "; Byte [] BS = encoding. ASCII. getbytes (sendstr ); Console. writeline ("Send message "); C. Send (BS, BS. length, 0); // send test information String recvstr = ""; Byte [] recvbytes = new byte [1, 1024]; Int bytes; Bytes = C. Receive (recvbytes, recvbytes. length, 0); // The slave server accepts the returned information. Recvstr + = encoding. ASCII. getstring (recvbytes, 0, bytes ); Console. writeline ("client get message: {0}", recvstr); // display the Server Response Information C. Close (); } Catch (argumentnullexception E) { Console. writeline ("argumentnullexception: {0}", e ); } Catch (socketexception E) { Console. writeline ("socketexception: {0}", e ); } Console. writeline ("press enter to exit "); Console. Readline (); } } } // Server end Using system; Using system. text; Using system. IO; Using system. net; Using system. net. Sockets; Namespace project1 { Class class2 { Static void main () { Try { Int Port = 2000; String host = "127.0.0.1 "; IPaddress IP = IPaddress. parse (host ); Ipendpoint IPE = new ipendpoint (IP, Port ); Socket S = new socket (addressfamily. InterNetwork, sockettype. Stream, protocoltype. TCP); // create a socket class S. BIND (IPE); // bind port 2000 S. Listen (0); // start listening Console. writeline ("Wait For connect "); Socket temp = S. Accept (); // create a new socket for the new connection. Console. writeline ("Get a connect "); String recvstr = ""; Byte [] recvbytes = new byte [1, 1024]; Int bytes; Bytes = temp. Receive (recvbytes, recvbytes. length, 0); // receive information from the client Recvstr + = encoding. ASCII. getstring (recvbytes, 0, bytes ); Console. writeline ("Server get message: {0}", recvstr); // display information sent from the client String sendstr = "OK! Client send message sucessful! "; Byte [] BS = encoding. ASCII. getbytes (sendstr ); Temp. Send (BS, BS. length, 0); // return the client success message Temp. Close (); S. Close (); } Catch (argumentnullexception E) { Console. writeline ("argumentnullexception: {0}", e ); } Catch (socketexception E) { Console. writeline ("socketexception: {0}", e ); } Console. writeline ("press enter to exit "); Console. Readline (); } } } |
The preceding example uses the socket class. The system. net. Socket namespace also provides two abstract advanced classes: tcpclient, udpclient, and networkstream for communication stream processing. Let's take a look at the example below.
Client
Tcpclient = new tcpclient (Host IP address, port number ); Networkstream NS = tcp. client. getstream (); |
Server
Tcplistener = new tcplistener (listener port ); Tcplistener. Start (); Tcpclient = tcplistener. accepttcpclient (); Networkstream NS = tcpclient. getstream (); |
The server uses tcplistener to listen, instantiate the connected object as a tcpclient, and call tcpclient. the getstream () method returns the network stream instantiated as a networlstream stream. The following describes how to send and receive streams.
If udpclient is used, udpclient is directly instantiated and then the send and receive methods of udpclient are called. Note that udpclient does not return network streams, that is, there is no getstream method, therefore, it cannot be streamed. When UDP is used for communication, do not listen to the server.
Now we have a general understanding of the. NET socket communication process. Next we will make a slightly complex program, a broadcast C/S chat program.
The client design requires a ListBox to display the chat content. A textbox inputs what you want to say, a button sends a message, and a button establishes a connection.
Click the button to create a connection. A dialog box is displayed, prompting you to enter the IP address, port, and nickname of the connection server to start an acceptance thread, receives information from the server and displays it on ListBox.
The server has two buttons, one starting service, one t dropping the client with established connection, and one ListBox displaying the IP address and port of the Client Connected to the server.
The most important thing is the issue of string encoding. You need to encode the string to be transmitted according to utf8, and then restore it to gb2312 when accepting the code. Otherwise, the Chinese display will be garbled.
Another is the receiving thread. Here I write a while (ture) loop to constantly judge whether there is information flowing in. If there is any, it will receive it and display it on ListBox. There is a problem here. in net2.0, an exception is thrown when the staggered thread modifies the properties of the form space. It cannot be modified directly. You need to define a delegate to modify it.
When the client needs to be disconnected, such as clicking XX in the upper-right corner of the form, you need to define this. formclosing + = new system. windows. forms. formclosingeventhandler (this. closing );(. net2.0 is a formclosing System Event). In the closing () function, the server sends the close character to the server. The server judges the information sent from the client on all connections cyclically. If it starts with close, disconnect from the instance. If I enter close in the chat window, will the connection be disconnected? No, the IP address and nickname must be added at the beginning when the information entered in the chat window is sent to the server, so there is no conflict.