Continuation example analysis of asynchronous communication of socket programming model (Part One)

Source: Internet
Author: User
Tags continue execution implement connect requires socket thread
Programming | Asynchronous asynchronous client sockets do not suspend the application while waiting for the network operation to complete. Instead, it handles network connections on one thread using the standard. NET Framework Asynchronous programming model, and the application continues to run on the original thread. Asynchronous sockets apply to applications that use a large network or do not wait for network operations to complete to continue.

The Socket class follows the. NET Framework naming pattern of the asynchronous method; For example, the synchronous Receive method corresponds to the asynchronous BeginReceive and EndReceive methods.

The asynchronous operation requires the callback method to return the result of the operation. If the application does not need to know the result, no callback method is required. The code examples in this section illustrate how to use a method to start a connection with a network device and end a connection with a callback method, use a method to start sending data and use a callback method to finish sending, and how to use a method to start receiving data and use a callback method to end receiving data.

Asynchronous sockets use threads in multiple system thread pools to handle network connections. A thread is responsible for initializing the sending or receiving of data, and other threads are connecting to the network device and sending or receiving data. In the program source code, an instance of the System.Threading.ManualResetEvent class is used to suspend the execution of the main thread and send a signal when execution can continue.

In the client source code, in order to connect an asynchronous socket to a network device, the socket method initializes a socket and then calls the BeginConnect method, passing the remote endpoint representing the network device, the connection callback method, and the state object (that is, the client Socket). Used to pass state information between asynchronous invocations. The example implements the Connect method to connect the specified Socket to the specified endpoint. It takes a global manualresetevent:public IAsyncResult BeginConnect named Connectdone (
EndPoint remoteEP,
AsyncCallback Callback,
Object state
);

The connection callback method Connectcallback implement the AsyncCallback delegate. It connects to the remote device when the remote device is available, and then signals the completion of the connection to the application thread by setting ManualResetEvent Connectdone. The following client source code implements the Connectcallback method.

The Send sample method encodes the specified string data in ASCII format and sends it asynchronously to the network device represented by the specified socket.

Send callback method Sendcallback implement AsyncCallback delegate. It sends data when a network device is ready to receive. The following source code implements the Sendcallback method. It takes a global ManualResetEvent named Senddone.

Reading data from a client socket requires a state object that passes a value between asynchronous invocations. The following class is a sample state object that is used to receive data from a client socket. It contains fields such as a client socket, a buffer for receiving data, and a StringBuilder for saving incoming data strings. Place these fields in the state object so that the values of those fields are retained between multiple invocations to read data from the client socket.

public class StateObject {
Client socket.
Public Socket worksocket = null;
Size of receive buffer.
public const int buffersize = 256;
Receive buffer.
Public byte[] buffer = new Byte[buffersize];
Received data string.
Public StringBuilder sb = new StringBuilder ();
}//For simplicity, this class is not created in the client source code

The Receive Method Example sets the state object and then calls the BeginReceive method to read the data asynchronously from the client socket.

Receive callback method ReceiveCallback implement AsyncCallback delegate. It receives data from a network device and generates a message string. It reads one or more data bytes from the network into the data buffer, and then calls the BeginReceive method again until the data sent by the client is complete. After all data is read from the client, ReceiveCallback signals the completion of the data to the application thread by setting the ManualResetEvent Senddone.

The following is the client detailed implementation code

Using System;
Using System.Drawing;
Using System.Collections;
Using System.ComponentModel;
Using System.Windows.Forms;
Using System.Data;
Using System.Net;
Using System.Net.Sockets;
Using System.Threading;
Using System.Text;
namespace Chat _socket_client
{
<summary>
Summary description of the Form1.
</summary>
public class Form1:System.Windows.Forms.Form
{
Private System.Windows.Forms.Label label4;
Private System.Windows.Forms.Label label3;
Private System.Windows.Forms.Label Label2;
Private System.Windows.Forms.Label Label1;
Private System.Windows.Forms.Button btnstop;
Private System.Windows.Forms.Button btnsend;
Private System.Windows.Forms.TextBox Txtport;
Private System.Windows.Forms.TextBox Txtserver;
Private System.Windows.Forms.RichTextBox rtbsend;
Private System.Windows.Forms.RichTextBox rtbreceive;
Private System.Windows.Forms.StatusBar statusBar1;
Private System.Windows.Forms.Button Btnconnect;
Private IPAddress hostipaddress;
Private IPEndPoint Server;
Private Socket sock;
Private Const int buffersize=256;
Private byte[] Buffer=new byte[buffersize];
private static ManualResetEvent connectdone=new ManualResetEvent (false);
private static ManualResetEvent senddone=new ManualResetEvent (false);
<summary>
The required designer variable.
</summary>
Private System.ComponentModel.Container components = null;

Public Form1 ()
{
//
Required for Windows Forms Designer support
//
InitializeComponent ();

//
TODO: Add any constructor code after the InitializeComponent call
//
}

<summary>
Clean up all resources that are in use.
</summary>
protected override void Dispose (bool disposing)
{
if (disposing)
{
if (Components!= null)
{
Components. Dispose ();
}
}
Base. Dispose (disposing);
}

Code generated #region the Windows forms Designer
<summary>
Designer supports required methods-do not use the Code editor to modify
The contents of this method.
</summary>
private void InitializeComponent ()
{
This.label4 = new System.Windows.Forms.Label ();
This.label3 = new System.Windows.Forms.Label ();
This.label2 = new System.Windows.Forms.Label ();
This.label1 = new System.Windows.Forms.Label ();
This.btnstop = new System.Windows.Forms.Button ();
This.btnsend = new System.Windows.Forms.Button ();
This.btnconnect = new System.Windows.Forms.Button ();
This.txtport = new System.Windows.Forms.TextBox ();
This.txtserver = new System.Windows.Forms.TextBox ();
This.rtbsend = new System.Windows.Forms.RichTextBox ();
this.rtbreceive = new System.Windows.Forms.RichTextBox ();
THIS.STATUSBAR1 = new System.Windows.Forms.StatusBar ();
This. SuspendLayout ();
//
Label4
//
This.label4.Location = new System.Drawing.Point (16, 152);
This.label4.Name = "Label4";
This.label4.Size = new System.Drawing.Size (64, 23);
This.label4.TabIndex = 22;
This.label4.Text = "Send message:";
//
Label3
//
This.label3.Location = new System.Drawing.Point (16, 64);
This.label3.Name = "Label3";
This.label3.Size = new System.Drawing.Size (64, 23);
This.label3.TabIndex = 21;
This.label3.Text = "Receive information:";
//
Label2
//
This.label2.Location = new System.Drawing.Point (216, 16);
This.label2.Name = "Label2";
This.label2.Size = new System.Drawing.Size (64, 23);
This.label2.TabIndex = 20;
This.label2.Text = "Listening port:";
//
Label1
//
This.label1.Location = new System.Drawing.Point (16, 16);
This.label1.Name = "Label1";
This.label1.Size = new System.Drawing.Size (56, 23);
This.label1.TabIndex = 19;
This.label1.Text = "server:";
//
Btnstop
//
This.btnStop.Location = new System.Drawing.Point (256, 256);
This.btnStop.Name = "Btnstop";
This.btnStop.TabIndex = 18;
This.btnStop.Text = "close Connection";
This.btnStop.Click + = new System.EventHandler (This.btnstop_click);
//
Btnsend
//
This.btnSend.Location = new System.Drawing.Point (144, 256);
This.btnSend.Name = "Btnsend";
This.btnSend.TabIndex = 17;
This.btnSend.Text = "Send Information";
This.btnSend.Click + = new System.EventHandler (This.btnsend_click);
//
Btnconnect
//
This.btnConnect.Location = new System.Drawing.Point (32, 256);
This.btnConnect.Name = "Btnconnect";
This.btnConnect.TabIndex = 16;
This.btnConnect.Text = "Request Connection";
This.btnConnect.Click + = new System.EventHandler (This.btnconnect_click);
//
Txtport
//
This.txtPort.Location = new System.Drawing.Point (288, 16);
This.txtPort.Name = "Txtport";
This.txtPort.Size = new System.Drawing.Size (48, 21);
This.txtPort.TabIndex = 15;
This.txtPort.Text = "19811";
//
Txtserver
//
This.txtServer.Location = new System.Drawing.Point (72, 16);
This.txtServer.Name = "Txtserver";
This.txtServer.TabIndex = 14;
This.txtServer.Text = "127.0.0.1";
//
Rtbsend
//
This.rtbSend.Location = new System.Drawing.Point (80, 152);
This.rtbSend.Name = "Rtbsend";
This.rtbSend.Size = new System.Drawing.Size (264, 96);
This.rtbSend.TabIndex = 13;
This.rtbSend.Text = "";
//
Rtbreceive
//
This.rtbReceive.Location = new System.Drawing.Point (80, 56);
This.rtbReceive.Name = "Rtbreceive";
This.rtbReceive.Size = new System.Drawing.Size (264, 96);
This.rtbReceive.TabIndex = 12;
This.rtbReceive.Text = "";
//
StatusBar1
//
This.statusBar1.Location = new System.Drawing.Point (0, 287);
This.statusBar1.Name = "StatusBar1";
This.statusBar1.ShowPanels = true;
This.statusBar1.Size = new System.Drawing.Size (360, 22);
This.statusBar1.TabIndex = 23;
This.statusBar1.Text = "StatusBar1";
//
Form1
//
This. AutoScaleBaseSize = new System.Drawing.Size (6, 14);
This. ClientSize = new System.Drawing.Size (360, 309);
This. Controls.Add (THIS.STATUSBAR1);
This. Controls.Add (THIS.LABEL4);
This. Controls.Add (THIS.LABEL3);
This. Controls.Add (THIS.LABEL2);
This. Controls.Add (THIS.LABEL1);
This. Controls.Add (This.btnstop);
This. Controls.Add (This.btnsend);
This. Controls.Add (This.btnconnect);
This. Controls.Add (This.txtport);
This. Controls.Add (This.txtserver);
This. Controls.Add (This.rtbsend);
This. Controls.Add (this.rtbreceive);
This. Name = "Form1";
This. Text = "Chat program-client";
This. Closing + = new System.ComponentModel.CancelEventHandler (this. Form1_Closing);
This. ResumeLayout (FALSE);

}
#endregion

<summary>
The main entry point for the application.
</summary>
[STAThread]
static void Main ()
{
Application.Run (New Form1 ());
}

private void Btnconnect_click (object sender, System.EventArgs e)
{
Try
{
Hostipaddress=ipaddress.parse (Txtserver.text);
}
Catch{messagebox.show ("Please enter the correct IP address format.") ");}
Try
{
Server=new IPEndPoint (Hostipaddress,int32.parse (Txtport.text));
Sock=new Socket (ADDRESSFAMILY.INTERNETWORK,SOCKETTYPE.STREAM,PROTOCOLTYPE.TCP);
Sock. BeginConnect (Server,new AsyncCallback (Connectcallback), sock);
}
catch (Exception ee) {MessageBox.Show (EE). message);}
}
private void Connectcallback (IAsyncResult ar)
{
Try
{
Socket client= (socket) AR. asyncstate; Get status
Client. EndConnect (AR);
Try
{
Byte[] Bytedata=encoding.bigendianunicode.getbytes ("Ready, can call" + "\ r \ n");
Sock. BeginSend (Bytedata,0,bytedata.length,0,new AsyncCallback (Sendcallback), sock);
}
catch (Exception ee) {MessageBox.Show (EE). message);}
Statusbar1.text= "connected with host" +txtserver.text+ "Port" +txtport.text+ "successful Connection";
Thread Thread=new Thread (new ThreadStart (ThreadProc));
Thread. Start (); Start receiving data threads
Connectdone.set (); Sets the state of the specified event to terminate.
}
catch{}
}
private void Sendcallback (IAsyncResult ar)
{
try{
Socket client= (socket) AR. asyncstate;
Senddone.set ();
}
catch (Exception ee) {MessageBox.Show (EE). message);}
}
private void ThreadProc ()
{
Try
{
Sock. BeginReceive (Buffer,0,buffersize,0,new AsyncCallback (ReceiveCallback), sock);
}
catch (Exception ee) {MessageBox.Show (EE). message);}
}
private void ReceiveCallback (IAsyncResult ar)
{
Try
{
Socket client= (socket) AR. asyncstate;
int bytesread=client. EndReceive (AR);//end pending asynchronous read. Returns the number of bytes received.
StringBuilder sb=new StringBuilder ();
Sb. Append (Encoding.BigEndianUnicode.GetString (Buffer,0,bytesread))//Storing data
String CONTENT=SB. ToString (); Convert to String
Sb. Remove (0,content. Length); Clear SB Content
Rtbreceive.appendtext (content+ "\ r \ n");
Client. BeginReceive (Buffer,0,buffersize,0,new AsyncCallback (ReceiveCallback), client);
}
catch{}
}

private void Btnsend_click (object sender, System.EventArgs e)
{
Try
{
String strsend = "Client--->" +rtbsend.text+ "\ r \ n";
byte[] Bytesend = Encoding.BigEndianUnicode.GetBytes (strsend);
Sock. BeginSend (Bytesend,0,bytesend.length,0,new AsyncCallback (Sendcallback), sock);
}
Catch{messagebox.show ("Connection not established, cannot be sent.");}
}

private void Btnstop_click (object sender, System.EventArgs e)
{
Try
{
Sock. Close ();
Statusbar1.text= "+txtserver.text+" with the host "port" +txtport.text+ "Disconnected";
}
Catch{messagebox.show ("The connection has not been established, the shutdown is invalid");}
}

private void Form1_Closing (object sender, System.ComponentModel.CancelEventArgs e)
{
Try
{
Sock. Close ();
}
catch{}
}
}
}



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.