Question

J'expérimente avec la construction d'un socket serveur en C # et une question que je suis coincé sur est que lorsque je passe un AsyncCallback à mon socket BeginReceive méthode le rappel est d'être appelé trop tôt et je reçois nulle quand je lis AsyncState propriété du IAsyncResult.

Je pensais que je devais « fixe » en ajoutant

.AsyncWaitHandle.WaitOne(100);

Mais le problème est toujours en cours. Quelqu'un pourrait-il nous éclairer sur l'endroit où ce que je fais mal?

Mon code est la suivante (en abrégé):

   private void Main(){

        _listener.BeginAccept(new AsyncCallback(HandleConnection), null);
    }


    private void HandleConnection(IAsyncResult status)
    {
        SocketError socketRecieveError;

        _connectionSocket = _listener.EndAccept(status);
        _connectionSocket.BeginReceive(_receivedDataBuffer, 0, _receivedDataBuffer.Length, 0, out socketRecieveError,
                                      new AsyncCallback(HandleHandshake), _connectionSocket.Available);

        if(socketRecieveError !=  SocketError.Success)
            _logger.Log("Socket error: " + socketRecieveError);
    }


    private void HandleHandshake(IAsyncResult status)
    {

        status.AsyncWaitHandle.WaitOne(1000);

        int handshakeLength;

        try
        {
            handshakeLength = Convert.ToInt32(status.AsyncState); // <--- BOOOM
        }
        catch (Exception ex)
        {
            _logger.Log(ex.Message);
        }
 ..............
 }
Était-ce utile?

La solution

La propriété AsyncState de IAsyncResult contient l'objet défini par l'utilisateur qui contient des informations sur l'opération asynchrone ( MSDN ). Ceci est le même objet qui est fourni en tant que paramètre « état » lorsque l'opération asynchrone est invoquée.

Dans votre code, vous fournissez _connectionSocket.Available en tant qu'Etat utilisateur. Je suppose que vous voulez fournir votre méthode de rappel avec le nombre d'octets qui ont été reçus? Ce n'est pas la bonne façon de le faire.

serait la bonne façon de le faire:

private void HandleConnection(IAsyncResult status)
{
    SocketError socketRecieveError;

    _connectionSocket = _listener.EndAccept(status);
    _connectionSocket.BeginReceive(_receivedDataBuffer, 0, _receivedDataBuffer.Length, 0, out socketRecieveError, new AsyncCallback(HandleHandshake), null);

    if(socketRecieveError !=  SocketError.Success)
        _logger.Log("Socket error: " + socketRecieveError);
}

private void HandleHandshake(IAsyncResult ar)
{
    int bytesReceived = _connectionSocket.EndReceive(ar);

    ....
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top