Analysis on socket programming in C #

Source: Internet
Author: User
C # Is a new language launched by Microsoft with VS.net. As an emerging language, it has strong C ++ and RAD features such as VB. Moreover, Microsoft launched C # mainly to combat Sun's Java. Everyone knows the powerful functions of Java, especially in network programming. Therefore, C # Naturally lags behind others in network programming. This article will introduce some basic knowledge about implementing socket (Sockets) programming in C #, so that you can have a general understanding of this. First, I will introduce the concept of socket.

  Basic concepts of sockets:

Socket is the cornerstone of communication and the basic operation unit for network communication that supports TCP/IP protocol. The socket can be seen as the two-way communication endpoint of processes between different hosts. It forms a programming interface between a single host and the entire network. The socket exists in the communication domain. The communication domain is an abstract concept introduced to process General threads through socket communication. Sockets usually exchange data with sockets in the same domain (Data Exchange may also cross the boundaries of the domain, but some interpreter must be executed at this time ). Various processes use the same domain to communicate with each other using Internet Protocol clusters.

Sockets can be classified based on the communication nature, which is visible to users. Generally, applications only communicate with sockets of the same type. However, as long as the underlying communication protocol permits, different types of sockets can also communicate. There are two different types of sockets: stream socket and datagram socket.

  Working principle of sockets:

To communicate over the internet, you need at least one pair of sockets, one running on the client, which we call ClientSocket, And the other running on the server, which we call ServerSocket.

Based on the connection start method and the target to which the local socket is to be connected, the connection process between sockets can be divided into three steps: server listening, client request, and connection confirmation.

A server listener is a server socket that monitors the network in real time, instead of locating a specific client socket, but waiting for a connection.

A client request is a connection request initiated by a client socket. The target is a server socket. Therefore, the client socket must first describe the socket of the server to be connected, point out the address and port number of the socket on the server, and then submit a connection request to the socket on the server.

Connection Confirmation means that when the server socket listens to or receives a connection request from the client socket, it responds to the request from the client socket and creates a new thread, send the description of the server socket to the client. Once the client confirms the description, the connection is established. The server socket continues to be in the listening status, and continues to receive connection requests from other client sockets.
Socket programming example in C:

By briefly introducing the basic concepts of sockets and the basic principles for implementing socket programming, I think you have a preliminary understanding of socket programming. However, the above is only about the basic concepts and principles. It still requires some work to be applied. The best way to really understand basic concepts and principles is to manually create an instance. Next I will introduce you to an example of using C # To implement socket programming-Chat Room program.

This program is based on the C/S (server/client) architecture. The program contains a server-side application and a client application. First, run the server-side application on the server, and the server listening starts as soon as the application runs. Then, you can open the client application on the client. After the program is opened, it can be connected to the server application, that is, client requests. After the connection is confirmed, the client user can chat with other client users. There is no limit on the number of clients, and the "whisper" chat mode is also supported, and chat records are supported. So this is a very good example of learning socket programming. In addition, the multi-thread mechanism is also used in the program to process the information of each client. After each client and server are connected successfully, a thread is established between them. After multithreading is used, the client does not affect each other, even if one of the errors occurs, it does not affect the other.

Next, I will introduce the instance to you in detail:

Server programs:

1. Open VS.net and create a project named "Windows application" as the C # template. You may wish to name it "ChatServer ".

2. layout interface. You only need to add a ListBox control on the interface. This control is mainly used to display some user information of the client. The image is as follows:

3. Write the code of the server program.

For the server side, the main function is to listen to client connection requests and confirm their requests. The program starts a StartListening () thread.

Private void StartListening ()
{
Listener = new TcpListener (listenport );
Listener. Start ();
While (true)
{
Try
{
Socket s = listener. AcceptSocket ();
Clientsocket = s;
Clientservice = new Thread (new ThreadStart (ServiceClient ));
Clientservice. Start ();
}
Catch (Exception e)
{
Console. WriteLine (e. ToString ());
}
}
}

This thread is always running. When the server receives a connection request from the client, it opens a ServiceClient () thread to serve the client. After a connection is established, each client is assigned a socket of its own. At the same time, a Client class object is created. This object contains some information about the client, which is saved in an array list.

The Client class is as follows:

Using System;
Using System. Threading;

Namespace ChatServer
{
Using System. Net. Sockets;
Using System. Net;

///
/// Summary of the Client.
///
Public class Client
{
Private Thread clthread;
Private EndPoint endpoint;
Private string name;
Private Socket sock;

Public Client (string _ name, EndPoint _ endpoint, Thread _ thread, Socket _ sock)
{
// TODO: add the constructor logic here
Clthread = _ thread;
Endpoint = _ endpoint;
Name = _ name;
Sock = _ sock;
}

Public override string ToString ()
{
Return endpoint. ToString () + ":" + name;
}

Public Thread CLThread
{
Get {return clthread ;}
Set {clthread = value ;}
}

Public EndPoint Host
{
Get {return endpoint ;}
Set {endpoint = value ;}
}

Public string Name
{
Get {return name ;}
Set {name = value ;}
}

Public Socket Sock
{
Get {return sock ;}
Set {sock = value ;}
}
}
}

The main part of the program should be the ServiceClient () function. This function is an independent thread, and its main part is a while loop. In the loop body, the program processes various client commands. The server receives the string from the client in ASCII code, which contains a separator in the form of "|. The previous part of the string "|" is a specific command, including the CONN, CHAT, PRIV, and GONE types. The CONN command establishes a new client connection, sends the existing user list to the new user, and notifies other users that a new user is added. The CHAT Command sends new information to all users. The PRIV Command sends a private message to a user. The GONE command removes an existing user from the user list and notifies other users that the user has left. At the same time, the GONE command can set the Boolean variable keepalive to false to end the thread connected to the client. The ServiceClient () function is as follows:

Private void ServiceClient ()
{
Socket client = clientsocket;
Bool keepalive = true;

While (keepalive)
{
Byte [] buffer = new Byte [1024];
Client. Receive (buffer );
String clientcommand = System. Text. Encoding. ASCII. GetString (buffer );

String [] tokens = clientcommand. Split (new Char [] {'| '});
Console. WriteLine (clientcommand );

If (tokens [0] = "CONN ")
{
For (int n = 0; n
{
Client cl = (Client) clients [n];
SendToClient (cl, "JOIN |" + tokens [1]);
}
EndPoint ep = client. RemoteEndPoint;
Client c = new Client (tokens [1], ep, clientservice, client );
Clients. Add (c );
String message = "LIST |" + GetChatterList () + "\ r \ n ";
SendToClient (c, message );

LbClients. Items. Add (c );

}
If (tokens [0] = "CHAT ")
{
For (int n = 0; n
{
Client cl = (Client) clients [n];
SendToClient (cl, clientcommand );
}
}
If (tokens [0] = "PRIV ")
{
String destclient = tokens [3];
For (int n = 0; n
{
Client cl = (Client) clients [n];
If (cl. Name. CompareTo (tokens [3]) = 0)
SendToClient (cl, clientcommand );
If (cl. Name. CompareTo (tokens [1]) = 0)
SendToClient (cl, clientcommand );
}
}
If (tokens [0] = "GONE ")
{
Int remove = 0;
Bool found = false;
Int c = clients. Count;
For (int n = 0; n
{
Client cl = (Client) clients [n];
SendToClient (cl, clientcommand );
If (cl. Name. CompareTo (tokens [1]) = 0)
{
Remove = n;
Found = true;
LbClients. Items. Remove (cl );
}
}
If (found)
Clients. RemoveAt (remove );
Client. Close ();
Keepalive = false;
}
}
}

In this way, the server-side program is basically complete. (For the code for other requests, see the Form1.cs file in the source code.) The program running illustration is as follows:

Client Program:

1. Open VS.net and create a project with the C # template "Windows application". You may wish to name it "ChatClient ".

2. layout interface. Add a ListBox control (used to display the user list), a RichTextBox Control (used to display chat messages and system messages), and a TextBox Control (used to send messages) to the interface ), a CheckBox control (whether it is a whisper), a StatusBar control, and four Button controls ("connection", "Disconnect", "Start record", and "send "). For details about the attribute settings of each control, refer to the specific settings in the source code. The image after the interface is designed is as follows:

3. Write the code of the client program.

When the client tries to connect to the server, a connection must be established and must be registered with the server. The EstablishConnection () function uses a TcpClient to connect to the server, and creates a NetworkStream to send messages. In addition, the port number is the same as that on the server, both of which are 5555. The EstablishConnection () function is as follows:

Private void EstablishConnection ()
{
StatusBar1.Text = "connecting to server ";
Try
{
Clientsocket = new TcpClient (serveraddress, serverport );
Ns = clientsocket. GetStream ();
Sr = new StreamReader (ns );
Connected = true;
}
Catch (Exception)
{
MessageBox. Show ("cannot connect to the server! "," Error ",
MessageBoxButtons. OK, MessageBoxIcon. Exclamation );
StatusBar1.Text = "disconnected ";
}
}

After the connection to the server is successful, the program uses the RegisterWithServer () function to send a CONN command to the server. This command first sends the user name, and then obtains the list of all other users from the server. The list of all users is displayed in the ListBox control. This function is as follows:

Private void RegisterWithServer ()
{
Try
{
String command = "CONN |" + ChatOut. Text;
Byte [] outbytes = System. Text. Encoding. ASCII. GetBytes (command. ToCharArray ());
Ns. Write (outbytes, 0, outbytes. Length );

String serverresponse = sr. ReadLine ();
Serverresponse. Trim ();
String [] tokens = serverresponse. Split (new Char [] {'| '});
If (tokens [0] = "LIST ")
{
StatusBar1.Text = "connected ";
BtnDisconnect. Enabled = true;
}
For (int n = 1; n
LbChatters. Items. Add (tokens [n]. Trim (new char [] {'\ R',' \ n '}));
This. Text = clientname + ": connected to the server ";

}
Catch (Exception)
{
MessageBox. Show ("an error occurred during registration! "," Error ",
MessageBoxButtons. OK, MessageBoxIcon. Exclamation );
}
}

After that, of course, the chat between users is completed by the ReceiveChat () function. This function is an independent thread that processes messages received by all users and messages sent by users. It mainly processes commands such as CHAT, PRIV, JOIN, GONE, and QUIT. The processing method is similar to that on the server side. The specific function implementation is as follows:

Private void ReceiveChat ()
{
Bool keepalive = true;
While (keepalive)
{
Try
{
Byte [] buffer = new Byte [2048];
Ns. Read (buffer, 0, buffer. Length );
String chatter = System. Text. Encoding. ASCII. GetString (buffer );
String [] tokens = chatter. Split (new Char [] {'| '});

If (tokens [0] = "CHAT ")
{
RtbChatIn. AppendText (tokens [1]);
If (logging)
Logwriter. WriteLine (tokens [1]);
}
If (tokens [0] = "PRIV ")
{
RtbChatIn. AppendText ("Private from ");
RtbChatIn. AppendText (tokens [1]. Trim ());
RtbChatIn. AppendText (tokens [2] + "\ r \ n ");
If (logging)
{
Logwriter. Write ("Private from ");
Logwriter. Write (tokens [1]. Trim ());
Logwriter. WriteLine (tokens [2] + "\ r \ n ");
}
}
If (tokens [0] = "JOIN ")
{
RtbChatIn. AppendText (tokens [1]. Trim ());
RtbChatIn. AppendText ("has joined the Chat \ r \ n ");
If (logging)
{
Logwriter. WriteLine (tokens [1] + "has joined the Chat ");
}
String newguy = tokens [1]. Trim (new char [] {'\ R',' \ n '});
LbChatters. Items. Add (newguy );
}
If (tokens [0] = "GONE ")
{
RtbChatIn. AppendText (tokens [1]. Trim ());
RtbChatIn. AppendText ("has left the Chat \ r \ n ");
If (logging)
{
Logwriter. WriteLine (tokens [1] + "has left the Chat ");
}
LbChatters. Items. Remove (tokens [1]. Trim (new char [] {'\ R',' \ n '}));
}
If (tokens [0] = "QUIT ")
{
Ns. Close ();
Clientsocket. Close ();
Keepalive = false;
StatusBar1.Text = "the server has stopped ";
Connected = false;
BtnSend. Enabled = false;
BtnDisconnect. Enabled = false;
}
}
Catch (Exception ){}
}
}

Through the above functions, client programs can freely chat with each other, and users can also send private messages to each other. So the program has implemented the basic functions of the chat room, but in the end each user needs to exit normally, it will need to use the QuitChat () function. The specific implementation of this function is as follows:

Private void QuitChat ()
{
If (connected)
{
Try
{
String command = "GONE |" + clientname;
Byte [] outbytes = System. Text. Encoding. ASCII. GetBytes (command. ToCharArray ());
Ns. Write (outbytes, 0, outbytes. Length );
Clientsocket. Close ();
}
Catch (Exception)
{
}
}
If (logging)
Logwriter. Close ();
If (receive! = Null & receive. IsAlive)
Receive. Abort ();
This. Text = "client ";
}

So far, the main parts of the client program have been introduced. The message processing functions of some button controls can be found in the source code. At the same time, the program also has a chat record function, which is similar to the record function of popular chat software. However, we will not describe the source code here. If you are interested, you can study the source code later in this article.

In this way, the client program is complete. The program running diagram is as follows:

  Summary:

This article introduces the basic concepts of sockets and the basic principles for implementing socket programming, A good example shows you how to implement socket programming in C # And some programming skills. It is not difficult to find that using C # For socket programming or network programming has many advantages. The implementation of the Instance program is clear and easy to understand. It is a very good example. I hope you can study it well. We also hope that you can further improve the program to make it more powerful and more user-friendly.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.