Use .NET to access Internet (4)

zhaozj2021-02-17  54

Use asynchronous client sockets

Asynchronous client sockets do not suspend the application when waiting for the network operation to complete. Instead, it uses standard .NET framework asynchronous programming models to process network connections on a thread, and the application continues to run on the original thread. Asynchronous sockets apply to applications that use the network or to wait for network operations to complete.

The Socket class follows the .NET framework name mode of the asynchronous method; for example, synchronous Receive method corresponds to an asynchronous BEGINRECEIVE and EndRecEive method.

Asynchronous operation requires a callback method to return the results. If the application does not need to know the result, no callback method is required. The code example in this section explains how to start connecting to the network device using a method and use a callback method to start sending data using a method and use a callback method to complete the send, and how to start receiving data using a method. The received data is ended using the callback method.

Asynchronous sockets use a thread processing network connection in multiple system thread pools. A thread is responsible for initializing the transmission or reception of data; other threads complete the connection to the network device and transmit or receive data. In the following example, an instance of the System.Threading.manualReventEvent class is used to suspend the execution of the main thread and signal it can be issued.

In the example below, in order to connect the asynchronous socket to the network device, the Connect method initializes the Socket instance, then call the BegInnect method, transfer the remote endpoint of the network device, the connection callback method, and the status object (ie client Socket instance, Used to transfer status information between asynchronous calls). This example implements the Connect method to connect the specified Socket instance to the specified endpoint. It assumes that there is a global manualReveTevent called ConnectDone.

[C #]

Public Static Void Connect (Endpoint Remoteep, Socket Client) {

Client.beginconnect (remoteep,

New asyncCallback (ConnectCallback), Client;

ConnectDone.waitone ();

}

Connect the callback method ConnectCallback implements an AsyncCallback commission. It is connected to the remote device when the remote device is available, and then the signal is sent to the application thread by setting the ManualResetEvent ConnectDone. The following code implements the ConnectCallback method.

[C #]

Private Static Void ConnectCallback (IASYNCRESULT AR) {

Try {

// Retrieve The Socket from the state object.

Socket Client = (socket) ar.asyncstate;

// Complete The Connection.

Client.EndConnect (Ar);

Console.writeLine ("Socket Connected to {0}",

Client.remoteEndPoint.toString ());

// Signal That The Connection Has Been Made.

ConnectDone.set ();

} catch (exception e) {

Console.writeLine (E.TOString ());

}

}

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

[C #]

Private Static Void Send (Socket Client, String Data) {

// Convert the string data to byte data using ascii eNCoding.byte [] Bytedata = encoding.ascii.getbytes (data);

// Begin Sending The Data to The Remote Device.

Client.beginsend (Bytedata, 0, Bytedata.Length, Socketflags.none,

New asyncCallback (SendCallback), Client;

}

Send a callback method SendCallback implements an ASYNCCALLBACK commission. It sends data when the network device is ready to receive. The following example shows the implementation of the SendCallback method. It assumes that there is a global manualReveTevent instance called Senddone.

[C #]

Private static void sendcallback (IasyncResult ar) {

Try {

// Retrieve The Socket from the state object.

Socket Client = (socket) ar.asyncstate;

// Complete sending the data to the remote device.

Int bytessent = client.endsend (ar);

Console.writeLine ("Sent {0} bytes to Server.", Bytessent;

// Signal That Alltes Have Been Sent.

Senddone.set ();

} catch (exception e) {

Console.writeLine (E.TOString ());

}

}

The read data from the client socket requires a status object that transmits a value between asynchronous calls. The following class is an example state object for receiving data from the client sleeve. It contains the following fields: client sleeve, buffer for receiving data, and StringBuilder for saving incoming data strings. Place these fields in this status object so that the values ​​of these fields are reserved between multiple calls to read data from the client sleeve.

[C #]

Public class stateObject {

Public Socket Worksocket = null; // Client Socket.

Public const Int buffersize = 256; // size of receiving buffer.

Public Byte [] buffer = new byte [buffersize]; // receive buffer.

Public StringBuilder SB = new stringbuilder (); // received data string.

}

Receive method example sets the status object, and then call the BeginReceive method to read data from the client socket. The following example implements the Receive method.

[C #]

Private static void receive (socket client) {

Try {

// CREATE The State Object.

StateObject State = new stateObject ();

State.worksocket = client;

// Begin Receiving The Data from The Remote Device.

Client.BeginReceive (state.buffer, 0, stateObject.buffearsize, 0,

New asyncCallback, State);} catch (exception e) {

Console.writeLine (E.TOString ());

}

}

Receive a callback method ReceiveCallback implements an ASYNCCALLBACK commission. It receives data from the network device and generates a message string. It reads one or more data bytes from the network into the data buffer, then call the BeginReceive method again until the data sent by the client is completed. After reading all the data from the client, ReceiveCallback passes the signal to the application thread by setting the ManualReveTevent Senddone.

The sample code below implements the ReceiveCallback method. It assumes that there is a global string called Response (the string saves received strings) and a global manualReveTevent instance called ReceiveDone. The server must close the client sleeve to end the network session.

[C #]

Private Static Void ReceiveCallback (IASYNCRESULT AR) {

Try {

// Retrieve The State Object and The Client Socket

// from the async state object.

StateObject State = (stateObject) ar.asyncState;

Socket client = state.worksocket;

// read Data from The Remote Device.

Int bytesread = client.endreceive (ar);

IF (BytesRead> 0) {

// There Might Be More Data, So Store The Data Received So Far.

State.sb.Append (Encoding.ascii.getstring (state.buffer, 0, bytesread);

// Get the rest of the data.

Client.BeginReceive (state.buffer, 0, stateObject.buffearsize, 0,

New asyncCallback (ReceiveCallback), State;

} else {

// all the data has arrived; put it in response.

IF (state.sb.length> 1) {

Response = state.sb.tostring ();

}

// Signal That Alltes Have Been received.

Receivedone.set ();

}

} catch (exception e) {

Console.writeLine (E.TOString ());

}

}

Use a socket to listen

Listener or server socket opens a port on the network and waits for the client to connect to the port. Although there are other network address families and protocols, this example shows how to create remote services for TCP / IP networks.

The only address of the TCP / IP service is defined: combining the IP address of the host with the port number of the service to create endpoints for the service. Methods of DNS class return to information about network addresses supported by local network devices. When the local network device has multiple network addresses, or when the local system supports multiple network devices, the DNS class returns information about all network addresses, and the application must select the correct address for the service. Internet Assigned Numbers Authority (IANA) Defines the port number of public services (for more information, please visit http://www.iana.org/assignments/port-numbers). Other services can have registration port numbers in the range of 1, 024 to 65, 535. The following code example creates IpendPoint for the server by combining the first IP address returned by the DNS with the host selected from the registration port number.

[C #]

IPHOSTENTRY iphostinfo = dns.resolve (DNS.GETHOSTNAME ());

Ipaddress ipaddress = iphostinfo.addresslist [0];

IpendPoint LocalendPoint = New IpendPoint (iPadDress, 11000);

After determining the local endpoint, you must use the bind method to associate with the endpoint and use the Listen method to listen on the endpoint. Bind will trigger an exception if a particular address and port combination has been used. The following example illustrates how to associate the socket with IpendPoint.

[C #]

Listener.bind (localendpoint);

Listener.listen (100);

The Listen method is a single parameter that specifies the number of Socket pending connections that allowed before returning the server to the connection client. In this example, up to 100 clients can be placed in the connection queue before returning the server busy response to the 101 client.

Use synchronous server socket

Synchronous server sockets hang up the execution of the application until the connection request is received on the socket. Synchronous server sockets do not apply to applications that use the network in operation, but they may apply to simple web applications.

Use the BIND and LISTEN methods to set up Socket to listen on the endpoint, Socket can use the Accept method at any time to accept the incoming connection request. The application is suspended until the connection request is received when the Accept method is called.

When the connection request is received, the Accept returns a new Socket instance associated with the connection client. The following example reads the client data and displays the data on the console and then displays the data back to the client. Socket does not specify any message protocol, so the string "" tag the end of the message data. It assumes that the Socket instance named Listener has been initialized and bound to the endpoint.

[C #]

Console.WriteLine ("Waiting for a connection ...");

Socket handler = listener.accept ();

String Data = NULL;

While (true) {

BYtes = New byte [1024];

INT BYTESREC = Handler.Receive (Bytes);

Data = encoding.ascii.getstring (bytes, 0, bytesrec);

IF (Data.Indexof ("")> -1) {

Break;

}

}

Console.writeline ("Text Received: {0}", DATA); Byte [] MSG = Encoding.ASCII.GetBytes (DATA);

Handler.send (MSG);

Handler.shutdown (socketshutdown.both);

Handler.close ();

Use asynchronous server socket

Asynchronous server sockets use the .NET framework asynchronous programming model to process network service requests. The Socket class follows the standard .NET asynchronous naming mode; for example, synchronous accept methods correspond to asynchronous beaccept and endaccept methods.

Asynchronous server socket requires a method of starting to accept network connection requests, a callback method that processes the connection request and starts receiving network data, and a callback method ending receiving data. This section will further discuss all of these methods.

In the example below, to start accepting a network connection request, the method startListence initializes the socket and then use the BeginAccept method to start accepting a new connection. The callback method is adjusted when the new connection request is received on the socket. It is responsible for obtaining the Socket instance that will handle the connection and submits the socket to the thread that will process the request. Accept the callback method to implement the AsyncCallback commission; it returns Void and takes an IASYNCRESULT type parameter. The following example is a housing program for receiving a callback method.

[C #]

Void AcceptCallback (IASYNCRESULT AR) {

// Add the callback code here.

}

BeginAccept method Belts two parameters: ASYNCALLBACK delegate to accept the callback method and an object to pass status information to the callback method. In the following example, the listening socket passes to the callback method through the status parameter. This example creates an AsyncCallBack delegate and starts accepting a network connection.

[C #]

Listener.BeginAccept (

New asyncCallback (socketListener.acceptCallback),

Listener;

Asynchronous sockets use the thread in the system thread to process incoming connections. A thread is responsible for accepting the connection, and the other thread is used to handle each incoming connection, and a thread is responsible for receiving connection data. These threads can be the same thread, depending on the thread allocated by the thread pool. In the example below, the System.Threading.manualRestEvent class hangs the execution of the main thread and signals when executing can continue.

The following example shows the asynchronous method of creating an asynchronous TCP / IP socket on the local computer and starting to accept the connection. It assumes the following: There is a global manualReveTevent instance called Alldone, which is a member named the SocketListener class, and a callback method called AcceptCallback.

[C #]

Public void startlistence () {

IPhostentry iphostinfo = new dns.resolve (dns.getHostName ());

IpendPoint Localep = New IpendPoint (iPhostInfo.addresslist [0], 11000);

Console.writeline ("Local Address and Port: {0}", localep.tostring ());

Socket Listener = New Socket (localep.address.addressFamily,

Sockettype.stream, protocoltype.tcp;

Try {

Listener.bind (localep);

S.Listen (10); while (true) {

Alldone.reset ();

Console.WriteLine ("Waiting for a connection ...");

Listener.BeginAccept (

New asyncCallback (socketListener.acceptCallback),

Listener;

Alldone.waitone ();

}

} catch (exception e) {

Console.writeLine (E.TOString ());

}

Console.writeline ("Closing The Listener ...");

}

Accept the callback method (i.e., the AcceptCallback in the predend case) is responsible for signaling to the main application, allowing it to continue processing, establish a connection to the client and start reading the client data asynchronously. The following example is the first part of the AcceptCallback method implemented. This section of this method is sent to the primary application thread that allows it to continue processing and establish a connection with the client. It assumes that there is a global manualReveTevent instance called AlldOne.

[C #]

Public Void AcceptCallback (IasyncResult AC) {

alldone.set ();

Socket Listener = (socket) ar.asyncstate;

Socket Handler = Listener.ndAccept (AR);

// additional code to read data goes here.

}

The read data from the client socket requires a status object that transmits a value between asynchronous calls. The following example implements a status object for receiving a string from a remote client. It contains the following fields: client sleeve, data buffer for receiving data, and StringBuilder for creating data strings sent by the client. Place these fields in this status object so that the values ​​of these fields are reserved between multiple calls to read data from the client sleeve.

[C #]

Public class stateObject {

Public Socket Worksocket = NULL;

Public const Int buffersize = 1024;

Public Byte [] buffer = new byte [buffersize];

Public StringBuilder SB = new stringbuilder ();

}

This section begins to initialize an instance of the StateObject class, then call the BeginReceive method to begin reading data from the client sleeve to start using the BEGINRECEIVE method.

The following example shows a complete acceptcallback method. It assumes the following: There is a ManualReveTevent instance called AlldOne, defines the StateObject class, and defines the ReadCallback method in a class named SocketListener.

[C #]

Public Static Void AcceptCallback (IASYNCRESULT AR) {

// Get The socket That Handles The Client Request.

Socket Listener = (socket) ar.asyncstate;

Socket Handler = Listener.ndAccept (AR);

// Signal The Main Thread to Continue.

alldone.set ();

// CREATE The State Object.

StateObject State = new stateObject (); state.worksocket = handler;

Handler.BeginReceive (state.buffer, 0, stateObject.buffearsize, 0,

New asyncCallback (AsynchronoussocketListener.Readcallback), State;

}

The FINAL method that needs to be implemented for the asynchronous socket server is to return the read callback method of the data sent by the client. Like the transfer method, reading the callback method is also an AsyncCallback commission. This method reads one or more bytes from the client socket to the data buffer, then call the BeginReceive method again until the data sent by the client is completed. After reading the entire message from the client, the string is displayed on the console and turn off the server socket that processs the connection to the client.

The following example implements the REDCALLBACK method. It assumes that the StateObject class is defined.

[C #]

Public Void ReadCallback (IASYNCRESULT AR) {

StateObject State = (stateObject) ar.asyncState;

Socket Handler = State.Worksocket;

// ingd data from the client socket.

Int Read = Handler.Endreceive (ar);

// Data Was Read from The Client Socket.

IF (read> 0) {

State.sb.Append (Encoding.ASCII.GetString (state.buffer, 0, read);

Handler.BeginReceive (state.buffer, 0, stateObject.buffearsize, 0,

New asyncCallback (READCALLBACK), STATE);

} else {

IF (state.sb.length> 1) {

// all the data Has been read from the clia;

// Display it on the console.

String content = state.sb.tostring ();

Console.writeline ("Read {0} bytes from socket ./n data: {1}",

Content.Length, Content;

}

Handler.close ();

}

}

Synchronous client sleeve

The following sample program creates a client connected to the server. The client is generated with synchronization sockets, so hangs the execution of the client application until the server returns. The application sends a string to the server and then displays the string returned by the server.

[C #]

Using system;

Using system.net;

Using system.net.sockets;

Using system.text;

Public class synchronoussocketclient {

Public static void startclient () {

// Data Buffer for incoming data.

Byte [] bytes = new byte [1024];

// Connect to a Remote Device.

Try {

// Establish The Remote endpoint for the socket.

// the name of the

// Remote Device IS "host.contoso.com" .iphostentry iphostinfo = dns.resolve ("host.contoso.com");

Ipaddress ipaddress = iphostinfo.addresslist [0];

IpendPoint Remoteep = New IpendPoint (iPaddress, 11000);

// CREATE A TCP / IP Socket.

Socket Sender = New Socket (AddressFamily.InterneTwork,

Sockettype.stream, protocoltype.tcp;

// Connect The socket to the remote endpoint. Catch any errors.

Try {

Sender.connect (remoteep);

Console.writeLine ("Socket Connected to {0}",

Sender.RemoteEndPoint.toString ());

// encode the data string into a byte array.

Byte [] msg = encoding.ascii.getbytes ("this is a test );

// dend the data through the socket.

INT bytessent = sender.send (MSG);

// Receive The Response from the remote device.

INT BYTESREC = Sender.Receive (Bytes);

Console.writeline ("Echoed Test = {0}",

Encoding.ascii.getstring (bytes, 0, bytesRec);

// Release the socket.

Sender.shutdown (socketshutdown.both);

Sender.close ();

} catch (argumentnullexception ane) {

Console.writeline ("Argumentnullexce: {0}", Ane.toString ());

} catch (socketexception se) {

Console.writeline ("socketexception: {0}", se.toString ());

} catch (exception e) {

Console.writeline ("Unexpected Exception: {0}", E.TOSTRING ());

}

} catch (exception e) {

Console.writeLine (E.TOString ());

}

}

Public static int main (string [] args) {

STARTCLIENT ();

Return 0;

}

}

转载请注明原文地址:https://www.9cbs.com/read-28552.html

New Post(0)