Esempio di socket server asincrono

Mediante il seguente programma di esempio viene creato un server per la ricezione delle richieste di connessione dai client. Poiché il server viene generato con un socket asincrono, l'esecuzione dell'applicazione server non viene sospesa in attesa della connessione di un client. Viene ricevuta una stringa dal client, la stringa viene visualizzata nella console, quindi restituita nuovamente al client. La stringa proveniente dal client deve contenere la stringa "<EOF>" che segnala la fine del messaggio.

Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading


' State object for reading client data asynchronously
Public Class StateObject
    ' Client  socket.
    Public workSocket As Socket = Nothing
    ' Size of receive buffer.
    Public Const BufferSize As Integer = 1024
    ' Receive buffer.
    Public buffer(BufferSize) As Byte
    ' Received data string.
    Public sb As New StringBuilder() 
End Class 'StateObject

Public Class AsynchronousSocketListener
    
    ' Incoming data from the client.
    Public Shared data As String = Nothing
    
    ' Thread signal.
    Public Shared allDone As New ManualResetEvent(False)
    
    
    Public Sub New()
    End Sub 'New
    
    
    Public Shared Sub StartListening()
        ' Data buffer for incoming data.
        Dim bytes() As Byte = New [Byte](1024) {}
        
        ' Establish the local endpoint for the socket.
        ' The DNS name of the computer
        ' running the listener is "host.contoso.com".
        Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())
        Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
        Dim localEndPoint As New IPEndPoint(ipAddress, 11000)
        
        ' Intializes a TCP/IP socket.
        Dim listener As New Socket(AddressFamily.InterNetwork, _
            SocketType.Stream, ProtocolType.Tcp)
        
        ' Bind the socket to the local endpoint and listen for incoming 
        ' connections.
        Try
            listener.Bind(localEndPoint)
            listener.Listen(100)
            
            While True
                ' Set the event to nonsignaled state.
                allDone.Reset()
                
                ' Start an asynchronous socket to listen for connections.
                Console.WriteLine("Waiting for a connection...")
                listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), _
                listener)
                
                ' Wait until a connection is made before continuing.
                allDone.WaitOne()
            End While
        
        Catch e As Exception
            Console.WriteLine(e.ToString())
        End Try
        
        Console.WriteLine(ControlChars.Cr + "Press ENTER to continue...")
        Console.Read()
    End Sub 'StartListening
    
    
    Public Shared Sub AcceptCallback(ar As IAsyncResult)
        ' Signal the main thread to continue.
        allDone.Set()
        
        ' Get the socket that handles the client request.
        Dim listener As Socket = CType(ar.AsyncState, Socket)
        Dim handler As Socket = listener.EndAccept(ar)
        
        ' Create the state object.
        Dim state As New StateObject()
        state.workSocket = handler
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, _
            New AsyncCallback(AddressOf ReadCallback), state)
    End Sub 'AcceptCallback
    
    
    Public Shared Sub ReadCallback(ar As IAsyncResult)
        Dim content As [String] = [String].Empty
        
        ' Retrieve the state object and the handler socket
        ' from the asynchronous state object.
        Dim state As StateObject = CType(ar.AsyncState, StateObject)
        Dim handler As Socket = state.workSocket
        
        ' Read data from client socket. 
        Dim bytesRead As Integer = handler.EndReceive(ar)
        
        If bytesRead > 0 Then
            ' There might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, _
                bytesRead))
            
            ' Check for end-of-file tag. If it is not there, read 
            ' more data.
            content = state.sb.ToString()
            If content.IndexOf("<EOF>") > - 1 Then
                ' All the data has been read from the 
                ' client. Display it on the console.
                Console.WriteLine("Read {0} bytes from socket. " + _
                    ControlChars.Cr + " Data : {1}", content.Length, content)
                ' Echo the data back to the client.
                Send(handler, content)
            Else
                ' Not all data received. Get more.
                handler.BeginReceive(state.buffer, 0,StateObject.BufferSize, _
                    0, New AsyncCallback(AddressOf ReadCallback), state)
            End If
        End If
    End Sub 'ReadCallback
    
    
    Private Shared Sub Send(handler As Socket, data As [String])
        ' Convert the string data to byte data using ASCII encoding.
        Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)
        
        ' Begin sending the data to the remote device.
        handler.BeginSend(byteData, 0, byteData.Length, 0, _
            New AsyncCallback(AddressOf SendCallback), handler)
    End Sub 'Send
    
    
    Private Shared Sub SendCallback(ar As IAsyncResult)
        Try
            ' Retrieve the socket from the state object.
            Dim handler As Socket = CType(ar.AsyncState, Socket)
            
            ' Complete sending the data to the remote device.
            Dim bytesSent As Integer = handler.EndSend(ar)
            Console.WriteLine("Sent {0} bytes to client.", bytesSent)
            
            handler.Shutdown(SocketShutdown.Both)
            handler.Close()
        
        Catch e As Exception
            Console.WriteLine(e.ToString())
        End Try
    End Sub 'SendCallback
    
    'Entry point that delegates to C-style main Private Function.
    Public Overloads Shared Sub Main()
        System.Environment.ExitCode = _
        Main(System.Environment.GetCommandLineArgs())
    End Sub
    
    Overloads Public Shared Function Main(args() As [String]) As Integer
        StartListening()
        Return 0
    End Function 'Main
End Class 'AsynchronousSocketListener
[C#]
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

// State object for reading client data asynchronously
public class StateObject {
    // Client  socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 1024;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
// Received data string.
    public StringBuilder sb = new StringBuilder();  
}

public class AsynchronousSocketListener {
    
    // Incoming data from client.
    public static string data = null;

    // Thread signal.
    public static ManualResetEvent allDone = new ManualResetEvent(false);

    public AsynchronousSocketListener() {
    }

    public static void StartListening() {
        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        // Establish the local endpoint for the socket.
        // The DNS name of the computer
        // running the listener is "host.contoso.com".
        IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

        // Create a TCP/IP socket.
        Socket listener = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp );

        // Bind the socket to the local endpoint and listen for incoming connections.
        try {
            listener.Bind(localEndPoint);
            listener.Listen(100);

            while (true) {
                // Set the event to nonsignaled state.
                allDone.Reset();

                // Start an asynchronous socket to listen for connections.
                Console.WriteLine("Waiting for a connection...");
                listener.BeginAccept( 
                    new AsyncCallback(AcceptCallback),
                    listener );

                // Wait until a connection is made before continuing.
                allDone.WaitOne();
            }

        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();
        
    }

    public static void AcceptCallback(IAsyncResult ar) {
        // Signal the main thread to continue.
        allDone.Set();

        // Get the socket that handles the client request.
        Socket listener = (Socket) ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        // Create the state object.
        StateObject state = new StateObject();
        state.workSocket = handler;
        handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);
    }

    public static void ReadCallback(IAsyncResult ar) {
        String content = String.Empty;
        
        // Retrieve the state object and the handler socket
        // from the asynchronous state object.
        StateObject state = (StateObject) ar.AsyncState;
        Socket handler = state.workSocket;

        // Read data from the client socket. 
        int bytesRead = handler.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));

            // Check for end-of-file tag. If it is not there, read 
            // more data.
            content = state.sb.ToString();
            if (content.IndexOf("<EOF>") > -1) {
                // All the data has been read from the 
                // client. Display it on the console.
                Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                    content.Length, content );
                // Echo the data back to the client.
                Send(handler, content);
            } else {
                // Not all data received. Get more.
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
            }
        }
    }
    
    private static void Send(Socket handler, 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.
        handler.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), handler);
    }

    private static void SendCallback(IAsyncResult ar) {
        try {
            // Retrieve the socket from the state object.
            Socket handler = (Socket) ar.AsyncState;

            // Complete sending the data to the remote device.
            int bytesSent = handler.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to client.", bytesSent);

            handler.Shutdown(SocketShutdown.Both);
            handler.Close();

        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }
    }


    public static int Main(String[] args) {
        StartListening();
        return 0;
    }
}

Vedere anche

Esempio di socket client asincrono | Utilizzo di un socket server asincrono | Esempi di codice di socket