2012-09-17 13 views
18

Ho riscontrato un problema specifico per Windows 8 e VS2012.Windows 8 - TCP TCP AcceptAsync callback non attivato (bloccato da Console.ReadLine())

Ho un server socket TCP e un client e sto facendo alcuni test sulla rete locale. Con sysinternals TCPView, posso vedere che i pacchetti vengono inviati dal client TCP e arrivano al server TCP (vedo aumentare i contatori dei pacchetti).

Tuttavia, sembra che i dati non stiano raggiungendo lo stack dell'applicazione? La stessa build viene eseguita senza problemi su Windows 7.

Ho il firewall di Windows 8 disattivato ed eseguo entrambi i processi con autorizzazioni elevate su utenti di un dominio admin con UAC disattivato.

Quando connetto il client a un server esterno (in esecuzione su una macchina separata), tutto funziona correttamente. C'è qualcos'altro in Windows 8 che potrebbe proibire la comunicazione di dati TCP tra processi locali?

Grazie,

EDIT

per assicurarsi che nulla nella mia applicazione server sta causando questo problema, ho costruito un server TCP veloce in un'applicazione console, con il seguente codice per il costruttore presa:

listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

e ascoltare sullo stesso IP/Port locale come la mia applicazione server. Sto riscontrando lo stesso problema, posso telnet alla porta ma listenerSocket.AcceptAsync non viene mai colpito.

EDIT 2

Su ulteriore test, appers mio problema ha a che fare con l'uso delle chiamate di socket asincroni, cioè se uso le chiamate sincrone come socket.Accept(), l'applicazione di verifica sta funzionando normalmente. Tuttavia, quando utilizzo le chiamate socket Async, ad esempio socket.AcceptAsync(), sto riscontrando i problemi menzionati. Finora non sono riuscito a trovare alcuna menzione delle differenze tra win7 & 8 riguardo alle chiamate socket asincrone.

Ecco la mia app di esempio rapida che mostra che la richiamata asincrona non viene mai attivata. Questo frammento funziona bene in Windows 7 ma non funziona in Windows 8 (prova a telnet su 127.0.0.1: 7000).

class Program 
{ 
    private static SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs(); 

    static void Main(string[] args) 
    { 
     var listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     listenerSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7000)); 
     listenerSocket.Listen(100); 

     socketAsyncEventArgs.Completed += AcceptEventArg_Completed; 
     listenerSocket.AcceptAsync(socketAsyncEventArgs); 

     Console.ReadLine(); 
    } 

    private static void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e) 
    { 
     Console.WriteLine("AcceptEventArg_Completed"); 
    } 
} 

EDIT 3

ho trovato altri 2 segnalato lo stesso problema su Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/759913/socketasynceventargs-completed-doesnt-fire-in-net-framework-4-5 e http://connect.microsoft.com/VisualStudio/feedback/details/747218/saea-not-working-in-net-4-5-rp

considerando che il 2 ° uno è interessante come sembra concludere c'è un bug di Windows nella chiamata Console.ReadLine() e causa il problema e il blocco della richiamata asincrona. Se sostituisco Console.ReadLine() nel mio snippet con:

  while (true) 
     { 
      System.Threading.Thread.Sleep(10); 
     } 

tutto funziona correttamente.

+0

Si sta comunicando sull'IP pubblico della macchina o tramite localhost? –

+0

IP di rete locale (non localhost) – TJF

+0

Bene, sospetto fortemente un problema con il firewall, ma poiché non posso testarlo adesso è tutto quello che ho, mi dispiace. Hai provato manualmente a consentire l'app del server in Windows Firewall? –

risposta

0

mi capita di incontrare la stessa cosa quando stavo sviluppando applicazioni client e server TCP con SocketAsyncEventArgs

vi consiglio di provare questo primo.

  1. aperto Windows Firewall con protezione avanzata controllo delle regole in entrata/uscita per vedere se l'applicazione è bloccata.

  2. AssemblyInfo.cs aperte e cambio

[assembly: Guid ("06985fe3-80eb-48b4-940a-fd926e2f2053")]

a qualsiasi altro valore guid.

Cambiando questo, Windows penserà che questa è una nuova applicazione e se ci fossero delle restrizioni verso la vecchia applicazione, non sarà su quella nuova.

0

suona così finestre bug relativo al trattamento IOCP (forse solo di AcceptEx) su Windows 8, mentre altri I/O di blocco è in corso sullo stesso thread:

http://social.technet.microsoft.com/Forums/en-GB/winserver8gen/thread/5764cd0f-fda1-4cfa-ae35-808210bae77e

Quindi la connessione socket è accettato, ma la tua app non riceve mai la notifica di esso.

Forse Windows 8 fa un po 'strano, leggermente spezzato, voodoo per convertire IO sincrono come Console.Read in async internamente.

Si potrebbe semplicemente spostare il codice server in un thread diverso, altri metodi da provare potrebbero essere eseguire Accept in modo sincrono o modificare l'elaborazione della console in modo asincrono (non posso davvero provarlo perché non ho Windows 8).