2012-09-17 3 views
18

Występuje problem specyficzny dla systemu Windows 8 i VS2012.System Windows 8 - nieodebrane wywołanie zwrotne .NET TCP AcceptAsync (zablokowane przez Console.ReadLine())

Mam serwer gniazd TCP i klienta i przeprowadzam testy w sieci lokalnej. Z sysinternals TCPView, widzę, że pakiety są wysyłane z klienta TCP i docierają do serwera TCP (widzę wzrost liczników pakietów).

Wygląda jednak na to, że dane nie trafiają na stos aplikacji? Ta sama kompilacja działa bez problemów w systemie Windows 7.

Mam zaporę systemu Windows 8 wyłączoną i uruchamiam oba procesy z podwyższonymi uprawnieniami dla administratorów domeny z wyłączonym UAC.

Po podłączeniu klienta do zewnętrznego serwera (działającego na oddzielnym komputerze) wszystko działa poprawnie. Czy jest coś jeszcze w systemie Windows 8, które może uniemożliwić komunikację danych TCP między procesami lokalnymi?

Dzięki,

EDIT

aby upewnić się nic w mojej aplikacji serwera jest przyczyną tego problemu, I zbudował szybki serwer TCP w aplikacji konsoli z następującego kodu dla konstruktora gniazda:

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

i nasłuchuj na tym samym lokalnym IP/Port co aplikacja mojego serwera. Występuje ten sam problem, mogę telnet do portu, ale listenerSocket.AcceptAsync nigdy nie jest trafiony.

EDIT 2

Po dalszych badań, to appers mój problem ma coś wspólnego z wykorzystaniem połączeń wtyczkowych asynchroniczny, to znaczy, jeśli mogę użyć połączeń synchronicznych jak socket.Accept(), aplikacji testowej wykonuje się normalnie. Jednak podczas korzystania z wywołań funkcji Async, tj. Socket.AcceptAsync(), występują wymienione problemy. Do tej pory nie mogłem znaleźć żadnej wzmianki o różnicach między win7 w zakresie wywołań w gnieździe asynchronicznym w win7 &.

Oto moja krótka przykładowa aplikacja, która pokazuje, że asynchroniczne wywołanie zwrotne nie jest nigdy wyzwalane. Ten fragment działa dobrze w Windows 7, ale nie działa w Windows 8 (spróbuj telnetować do 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

znalazłem 2 inne zgłoszenie sam problem na Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/759913/socketasynceventargs-completed-doesnt-fire-in-net-framework-4-5 i http://connect.microsoft.com/VisualStudio/feedback/details/747218/saea-not-working-in-net-4-5-rp

Podczas gdy 2 jeden jest interesujący, gdyż wydaje się stwierdzić, że jest błąd systemu Windows w wywołaniu Console.ReadLine(), który powoduje problem i blokuje wywołanie zwrotne asynchroniczne. Jeśli zamieniam Console.ReadLine() w moim wycinku z:

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

wszystko działa poprawnie.

+0

Czy komunikujesz się za pośrednictwem publicznego adresu IP urządzenia lub za pośrednictwem lokalnego hosta? –

+0

IP sieci lokalnej (nie localhost) – TJF

+0

Cóż, mocno podejrzewałbym problem z firewallem, ale ponieważ nie mogę przetestować w tej chwili, to wszystko, co mam, przepraszam. Czy próbowałeś ręcznie, zezwalając na aplikację serwera w Zaporze systemu Windows? –

Odpowiedz

0

spotkam to samo, kiedy rozwój klienta i serwera aplikacji TCP z SocketAsyncEventArgs

Proponuję spróbować ten pierwszy.

  1. otwarty Zapora systemu Windows z zabezpieczeniami zaawansowanymi sprawdzić Reguły przychodzące/wychodzące aby sprawdzić, czy aplikacja jest zablokowana.

  2. otwarte AssemblyInfo.cs i zmienić

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

do każdej innej wartości guid.

Zmieniając to, system Windows będzie sądził, że jest to nowa aplikacja i jeśli istniały jakiekolwiek ograniczenia w stosunku do starej aplikacji, nie będzie to nowe.

0

Wygląda na to, że Windows błędów związanych z przetwarzaniem IOCP (ewentualnie tylko od AcceptEx) na Windows 8, podczas gdy inne blokowanie I/O jest w toku w tym samym wątku:

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

więc połączenie gniazdko jest akceptowany, ale twoja aplikacja nigdy nie otrzyma powiadomienia o tym.

Może Windows 8 robi dziwne, łamane, voodoo, aby konwertować synchroniczne IO jak konsola. Czytać wewnętrznie asynchronicznie.

Możesz po prostu przenieść swój kod serwera do innego wątku, inne sposoby obejścia tego problemu mogą polegać na tym, że możesz wykonać Akceptuj synchronicznie lub zmienić przetwarzanie konsoli na asynchroniczne (tak naprawdę nie mogę tego wypróbować, ponieważ nie mam systemu Windows 8).

Powiązane problemy