Socket multithreaded Programming in C #

Source: Internet
Author: User

C # is a new language that Microsoft has launched with Vs.net. As a new language, it has a strong C + +, and has the rad characteristics of VB. Moreover, Microsoft's main purpose in C # is to fight Sun's java. We all know the powerful features of the Java language, especially in the area of network programming. As a result, C # in the network programming is also naturally not behind people. This paper introduces some basic knowledge of implementing socket (Sockets) programming under C #, so that we can have a general understanding of this. First, let me introduce you to the concept of sockets.

Socket Basic Concepts:

Sockets are the cornerstone of communication and a basic operating unit for network communication that supports TCP/IP protocol. Sockets can be considered as endpoints of two-way communication between processes in different hosts, which form a programming interface between a single host and the entire network. Sockets exist in the communication domain, and the communication domain is an abstract concept that is introduced in order to deal with the common thread through socket communication. Sockets typically exchange data with sockets in the same domain (data exchange may also traverse the boundaries of a domain, but it is important to perform some sort of interpreter). Various processes use the same domain to communicate with each other using an Internet Protocol cluster.

Sockets can be categorized according to the nature of the communication, which is visible to the user. Applications generally communicate only between sockets in the same class. However, as long as the underlying communication protocol allows, different types of sockets can still communicate. There are two different types of sockets: Stream sockets and datagram sockets.

How sockets work:

To communicate over the Internet, you need at least one pair of sockets, one running on the client side, which we call Clientsocket and the other running on the server side, which we call ServerSocket.

Depending on how the connection is started and the destination to which the local socket is connected, the connection between sockets can be divided into three steps: Server listening, client request, connection acknowledgement.

The so-called server monitoring, is the server end socket does not locate the specific client socket, but in the state of waiting for the connection, real-time monitoring network status.

A client-side request is a connection request made by the client's socket, and the target of the connection is the server end socket. To do this, the client's socket must first describe the socket of the server it is connecting to, indicate the address and port number of the server-side socket, and then make a connection request to the server-side socket.

The so-called connection confirmation, when the server-side socket is heard or received a client socket connection request, it responds to the client socket request, set up a new thread, the server-side socket description to the client, once the client confirms the description, the connection is established. While the server-side socket continues to be in the listening state, it continues to receive connection requests from other client sockets.
socket Programming examples in C #:

By simply introducing the basic concept of socket and implementing the principle of socket programming, I think we have a preliminary understanding of socket programming. However, the above introduction is only the basic concepts and principles, to really use or need some work. The best way to really understand the basic concepts and principles is to do an instance of yourself, and I'll introduce you to a good example of using C # for socket programming--chat room programs.

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 start the server listening as soon as the program runs. The client's application can then be opened on the client computer. When the program is opened, it can be connected to the server-side application, that is, client requests. After the connection is confirmed, the client user can chat with other client users. There is no limit to the number of clients, while also supporting "whisper" chat mode to support chat history. So this is a pretty good example of learning socket programming. Furthermore, the multithreading mechanism is used in the program to handle the information of each client. After each client-server connection succeeds, a thread is established between them. With multithreading, there is no interaction between the clients, even if one of the errors does not affect the other.

Below, I'll give you a concrete introduction to this example:

Server-side programs:

1. Open Vs.net, create a new C # template for the Windows application project, and name it "Chatserver".

2. Layout interface. Simply add a ListBox control to the interface, which is primarily used to display some information about the client's users. The image is as follows:



3. The code of the server-side program is written.

For the server side, the primary function is to listen for the client's connection request and confirm its request. The program opens a startlistening () thread at the outset.

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 ());
}
}
}
The thread is always in the running state. When the server side receives a connection request from the client, it opens a serviceclient () thread to service the client. When a connection is established, each client is given a socket that belongs to it. At the same time, a client class object is created.    The object contains some information about the client, which is stored in an array list. The client classes are as follows:

Using System;
Using System.Threading;

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

///
A summary description 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 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 body part of the program should be the ServiceClient () function. The function is a separate thread whose main part is a while loop. In the loop body, the program handles various client commands. The server side receives an ASCII-given string from the client, which contains a "|" The delimiter of the form. "|" in the string The previous sections were specific commands, including Conn, CHAT, PRIV, gone four types. The conn command establishes a new client connection, sends an existing list of users to the new user, and informs the other user that a new user has joined. The chat command sends the new information to all users. The Priv command sends a private whisper to a user. The Gone command removes a left user from the list of users and informs other users that someone has left. Also, 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. (Other slightly minor code can refer to the Form1.cs file in the source code) the program runs as shown below:


Client program:

1. Open Vs.net, create a new C # template for the Windows application project, and name it "ChatClient".

2. Layout interface. Add a ListBox control to the interface (to display the list of users), a RichTextBox control (for displaying chat messages and system messages), a TextBox control (for sending messages), a CheckBox control (to determine if it is a private message), A StatusBar control and four button controls (connection, disconnect, start record, send, respectively). The property settings for each control can be found in the source code, here withheld. The image after the interface design is as follows:



3. The code of the client program is written.

When a client attempts to connect to the server, a connection must be established and registered with the server. The Establishconnection () function uses a tcpclient to get a connection to the server and creates a NetworkStream to send the message. Also, the port number and the server side are consistent, all 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 with the server is successful, the program sends a conn command to the server using the Registerwithserver () function. The command first sends the name of the user and then obtains a list of all other users from the server side, and all user lists are displayed in the ListBox control. The 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 Server";


}
catch (Exception)
{
MessageBox.Show ("There was an error registering! "," Error ",
MessageBoxButtons.OK, messageboxicon.exclamation);
}
}
After this, of course, is the chat between users, by the Receivechat () function to complete. The function is a separate thread that handles all the messages that the user obtains and the messages that the user sends. It mainly deals with commands such as chat, PRIV, JOIN, GONE, qu99v, and so on, with a similar approach to server-side. The specific functions are implemented 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 ("have left the chat\r\n");
if (logging)
{
LogWriter. WriteLine (tokens[1]+ "have left the Chat");
}
LbChatters.Items.Remove (Tokens[1]. Trim (new char[]{' \ R ', ' \ n '});
}
if (tokens[0] = = "qu99v")
{
Ns. Close ();
Clientsocket. Close ();
KeepAlive = false;
Statusbar1.text = "Server Side stopped";
Connected= false;
btnsend.enabled = false;
btndisconnect.enabled = false;
}
}
catch (Exception) {}
}
}
Through some of the above functions, the client program can be free to chat between the various users can also send each other a whisper. So the program has realized the basic function of the chat room, but the end of each user to normal exit, it is necessary 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. There are also message handler functions for button controls that can be found in source code. At the same time, the program also has a chat record function, this feature and now popular chat software recording function similar. However, confined to the space, here is not introduced, interested readers can study the source code later in this article.

Socket multithreaded Programming in C #

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.