2011-04-12 3 views
4

J'ai une application client/serveur TCP pour communiquer avec un périphérique Windows CE via une connexion ActiveSync. Le client et le serveur utilisent tous les deux des sockets asynchrones (c'est-à-dire les fonctions Socket.Begin* et Socket.End*). Lorsque le client et le serveur s'exécutent sur mon bureau, tout fonctionne exactement comme prévu, mais lorsque le client s'exécute sur le périphérique Windows CE connecté via ActiveSync, j'obtiens toujours un SocketException sur ReceiveCallback après avoir appelé Socket.Shutdown (lorsque le périphérique démarre) la déconnexion). L'exception est pleine:Problème d'arrêt progressif du socket TCP Async .NETCF

System.Net.Sockets.SocketException: An error message cannot be displayed because an optional resource assembly containing it cannot be found 
at System.Net.Sockets.Socket.ReceiveNoCheck() 
at ReceiveAsyncRequest.doRequest() 
at AsyncRequest.handleRequest() 
at WorkerThread.doWork() 
at WorkerThread.doWorkI() 
at WorkItem.doWork() 
at System.Threading.Timer.ring() 

Tout semble également fonctionner correctement si le serveur (en cours d'exécution sur le bureau) déclenche la déconnexion. J'ai quelques idées sur la façon d'éviter cela, y compris interdisant les déconnexions initiées par le périphérique et ignorer toutes les exceptions après avoir initié une déconnexion. Cependant, j'aimerais savoir pourquoi cela se produit et s'il y a une meilleure façon de le gérer.

La déconnexion et ReceiveCallbacks (identique sur le plan opérationnel sur le serveur et le client) sont:

public bool Disconnect(StateObject state) 
{ 
    try{ 
    if(state.isDisconnecting) return false; 

    state.isDisconnecting = true; 
    state.sock.Shutdown(SocketShutdown.Both); 
    //Wait for sending and receiving to complete, but don't wait more than 10 seconds 
    for(int i=0; i<100 && (state.isSending || state.isReceiving); i++){ 
     System.Threading.Thread.Sleep(100); 
    } 

    /* Log the disconnect */ 

    state.sock.Close(); 

    return true; 
    } catch (Exception e){ 
    /* Log the exception */ 

    return false; 
    } 
} 

private void ReceiveCallback(IAsyncResult iar) 
{ 
    StateObject state = (StateObject)iar.AsyncState; 
    try{ 
    //handle the new bytes in the buffer. 
    int recv = state.sock.EndReceive(iar); 

    //Handle the buffer, storing it somewhere and verifying complete messages. 

    if(recv > 0){ 
     //start listening for the next message 
     state.sock.BeginReceive(state.recvBuffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, new AsyncCallback(ReceiveCallback), state); 
    } else { 
     state.isReceiving = false; 
     Disconnect(state); 
    } 
    } catch (Exception e){ 
    /* Log the exception */ 
    } 
} 

//For reference, A StateObject looks kinda like this: 
public class StateObject 
{ 
    public const int BUFFER_SIZE = 1024; 

    public Socket sock = null; 
    public bool isSending = false; 
    public bool isReceiving = false; 
    public bool isDisconnecting = false; 

    public byte[] recvBuffer = new byte[BUFFER_SIZE]; 
    public byte[] sendBuffer = new byte[BUFFER_SIZE]; 

    //Other stuff that helps handle the buffers and ensure complete messages, 
    // even when TCP breaks up packets. 
} 
+2

Ne supposez jamais que le CF et le framework complet se comporteront de manière identique. http://blog.opennetcf.com/ctacke/2008/10/02/BehavioralDifferencesBetweenTheCFAndFFx.aspx – ctacke

+0

@ctacke, ouais, je commence vraiment à comprendre ça, aussi pénible que ça ... – chezy525

+0

as-tu le exception lors du débogage? (existe-t-il un débogueur distant pour WinCE?) existe-t-il une InnerException avec plus de détails? – user1859022

Répondre

0

Il afin d'obtenir l'exception réelle peut-être essayer comprendre dans quelle bibliothèque dont il a besoin et le déployer?

0

Si un message s'affiche sur votre appareil, car le message n'est pas installé sur votre appareil. Vous devez installer un netcf.messages.cab. Vous trouverez ici:

C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\Diagnostics 

Après avoir installé ce fichier CAB, exécutez à nouveau votre application et poster la nouvelle erreur que vous obtenez.