Windows 8 - .NET TCP AcceptAsync callback not firing (blocked by Console.ReadLine()) - c#

I'm experiencing an issue specific to Windows 8 and VS2012.
I have a TCP socket server and client and am doing some testing on the local network. With sysinternals TCPView, I can see that packets are sent from the TCP client and arrive at the TCP Server (I see the packet counters increase).
However, it appears as if the data is not making it to the application stack?
The very same build runs without issues on Windows 7.
I have the Windows 8 firewall turned off and run both process with elevated permissions on a domain admin users with UAC turned off.
When I connect the client to a an outside server (running on a separate machine), everything works fine.
Is there anything else in Windows 8 that could prohibit TCP data communication between local processes?
Thanks,
EDIT
To make sure nothing in my server application is causing this issue, I built a quick TCP server in a console application, with the following code for the socket constructor:
listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
and listen on the same local IP/Port as my server application.
I'm experiencing the same issue, I can telnet to the port but listenerSocket.AcceptAsync is never hit.
EDIT 2
Upon further testing, it appers my issue has something to do with the use of the Async socket calls, i.e. if I use the synchronous calls like socket.Accept(), the test application is performing normally. However, when I use Async socket calls, i.e. socket.AcceptAsync(), I'm experiencing the issues mentioned. So far I couldn't find any mention of differences between win7 & 8 in regards to async socket calls.
Here's my quick sample app that shows that the async callback is never triggered. This snippet works fine in Windows 7 but does not work in Windows 8 (try to telnet to 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
I found 2 others reporting the same issue on Microsoft Connect:
https://connect.microsoft.com/VisualStudio/feedback/details/759913/socketasynceventargs-completed-doesnt-fire-in-net-framework-4-5
and
http://connect.microsoft.com/VisualStudio/feedback/details/747218/saea-not-working-in-net-4-5-rp
Whereas the 2nd one is interesting as it seems to conclude there is a Windows bug in the Console.ReadLine() call and it is causing the issue and blocking the async callback. If I replace Console.ReadLine() in my snippet with:
while (true)
{
System.Threading.Thread.Sleep(10);
}
everything works fine.

See this: GetQueuedCompletionStatus can't dequeue IO from IOCP if the thread which originally issued the IO is blocking in ReadFile under windows 8
It's a bug in windows 8 and 2012 and affect all programs which used AcceptEx and ReadFile. As for now, only these two functions are known affected.

I meet the same thing when I was developing Tcp server and client applications with SocketAsyncEventArgs
I suggest you try this first.
open Windows firewall with Advanced Security
check the inbound / outbound rules to see if your application is blocked.
open AssemblyInfo.cs and change the
[assembly: Guid("06985fe3-80eb-48b4-940a-fd926e2f2053")]
to any other guid value.
By changing this, windows will think this is a new application and if there were any restrictions towards the old application, it wont be on the new one.

Sounds like this windows bug relating to the IOCP processing (possibly just of AcceptEx) on Windows 8 while other blocking I/O is in progress on the same thread:
http://social.technet.microsoft.com/Forums/en-GB/winserver8gen/thread/5764cd0f-fda1-4cfa-ae35-808210bae77e
So the socket connection is accepted, but your app never recieves notification of it.
Maybe Windows 8 does some weird, slighly broken, voodoo to convert synchronous IO like Console.Read into async internally.
You could just move your server code into a different thread, other workarounds to try might be to perform Accept synchonously or to change the console processing to be asynchronous (I can't really try that as I don't have Windows 8).

Related

TcpListener.AcceptSocketAsync issues in Windows 7

I have old .NET code which uses TcpListener and needs to run on Windows 7 and Windows 10 PCs.
Initially it uses a separate thread where a blocking call to TcpListener.AcceptSocket is used. On application exit Thread.Abort() is called to kill that thread. All incoming connections work ok on both Win 7 and Win 10, but Abort causes some issues. It is a rough way to exit, not recommended anyway.
I change it to use Tasks + TcpListener.AcceptSocketAsync. It is more elegant solution + fixes exit issues caused by Thread.Abort(). Works perfectly on Win 10 but on Win 7 client connections don't pass. Note, it is the same Win 7 PC where the synchronous method works. I can test it in minutes by rolling code back and forth.
Here is an extract of async network code:
var listener = new TcpListener(IPAddress.Loopback, port)
{
ExclusiveAddressUse = false
};
listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
listener.Start();
while(!stop)
{
Socket sck;
try
{
sck = await listener.AcceptSocketAsync();
}
catch...
// process exceptions, exit conditions, read data
}
Does anyone know about specific issues of TcpListener.AcceptSocketAsync on Win 7?
.NET framework 4.7.2 and Windows 7 x64 are used.
Thanks!

In UWP TcpListener AcceptTcpClientAsync doesn't work

I'm porting some TcpListener/TcpClient/etc code to work on UWP. However, the most basic operations which work in a generic windows c# app are failing for me under UWP.
The most basic operation, such as waiting for a TcpClient is failing:
private async Task TestTcpListening()
{
Debug.WriteLine("Creating TcpListneer");
int portNumber = 8554;
TcpListener listener = new TcpListener(IPAddress.Any, portNumber);
listener.Start();
while(true)
{
Debug.WriteLine("Waiting on TcpListener to accept client");
TcpClient client = await listener.AcceptTcpClientAsync();
Debug.WriteLine(string.Format("We got a client! {0}", client));
}
}
If I run this code in a generic windows console application, the "We got a client" bit runs when I tickle the localhost URL. If this runs in a UWP application, it waits forever and the calling app times out.
NOTES:
I've selected the Internet (Client & Server), Internet, and Private Networks capabilities in the Package.appxmanifest
I'm porting an RTSP server, that works fine as a general windows app. As such, the URI I'm using is "rtsp://localhost:8554". When built as a command-line windows app the above code works as expected, when pointing VLC to that URI. The UWP version of the same code waits forever, and VLC times out.
I'm completely new to Windows, so I don't yet know what I don't know.
THOUGHTS:
Do I need to enable "rtsp:" protocol access to the app somehow? I don't want the app to open when an rtsp: url is hit. I just want incoming connections to be handled.
Being new to Windows development, and in particular to UWP, I didn't know about the loopback restriction. For the time being, for testing my RTSP port, using VLC on another computer on the same network resolves my issue above.

How to detect a network was broken down with ZeroMQ monitor mechanism?

A. Description
I am using ZeroMQ monitor and I find that it works when logic disconnection but does not work when network broken down (unplug my cable).
For example:
I launch client app on an android pad, then launch a server app on my windows laptop. They are connected through a router with cables.
Everything will be OK with monitor if I close or open either client app or server app manually. Namely, the monitor on both sides can receive a 'Connect' or an 'Accept' and a 'Disconnect' event.
But If I unplug cable on the server side, while the client and server are connected and running, the monitors on both sides can not detect the 'Disconnect' event.
Is the monitor designed like this?
If so, are there any solutions to detect network broken down ( a cable unplug event ) except heartbeats?
If not, how to use the ZeroMQ's original monitor mechanism to solve this problem? Can a setTCPKeepAlive() interface be useful?
B. System environment
My scenario is as below.
Client
OS: Android, running on a pad, IDE: Android studio 2.3, lib:jeromq-0.4.3
// Java Code
String monitorAddr = "inproc://client.req";
ZContext ctx = new ZContext();
ZMQ.Socket clientSocket = ctx.createSocket(ZMQ.REQ);
clientSocket.monitor(monitorAddr,ZMQ.EVENT_ALL);
// Then start a montitor thread which is implemented by my own.
Server
OS: Windows 7 ( 64 bit ), running on my laptop, IDE: VS2013, lib: Clrzmq4
// C# Code
const string MonitorEndpoint = "inproc://server.rep";
var ctx = new ZContext();
var serverSocket = new ZSocket(ctx,ZSocketType.REP);
ZError error;
// Create serverSocket pair socket
if (!serverSocket.Monitor(MonitorEndpoint, ZMonitorEvents.AllEvents, out error))
{
if (error == ZError.ETERM)
return ; // Interrupted
throw new ZException(error);
}
// Create a monitor
ZMonitor _monitor = ZMonitor.Create(ctx, MonitorEndpoint);
_monitor.AllEvents += _monitor_AllEvents;
_monitor.Start();
AFAIK there is no built in heartbeat within ZeroMQ. I know there was some discussion on the topic within the ZMQ community some years ago, and that discussion may still be going on.
It is comparatively simple to incorporate your own heartbeat messaging in your application's use of ZeroMQ, especially if you use something like Google Protocol Buffers to encode different message types; the heartbeat is just another message.
Doing heartbeats in your application (rather than relying on some inbuilt mechanism) is ultimately more flexible; you can choose the heartbeat rate, you can choose what to do if the heartbeat fails, you can decide when heartbeating is important and not important, etc.
Consider heartbeats within a PUB/SUB pattern; it's a bit difficult for the ZMQ authors to decide on your behalf what connection / disconnection / connection-break events matter to you. And if they do build in a mechanism, but an application developer didn't want it, then it is a waste of bandwidth.
It's far easier for the ZMQ authors to leave that kind of application architectural issue to the application author (that's you!) to deal with.
With your specific example, an unplugged network cable simply looks (so far as any software can determine) like no traffic is flowing; it's the same as the application not sending anything. ZMQ doesn't send anything if the application hasn't sent anything.
If you look at the events that the socket monitor can report on, they're all the consequence of something flowing over the network connection, or something done to the socket by the application.
Trying to go lower than ZMQ protocol itself and access the TCP connection that specific ZeroMQ sockets use (while others do not) doesn't sound like a good idea; it would required to break encapsulation in multiple classes.
The answer #bazza gave in 2017 was entirely correct at the time.
However, newer versions of ZMQ (specifically ZMTP) include an heartbeat functionality.
Check ZMQ documentation for
socketOpt
Java functions
name
purpose
ZMQ_HEARTBEAT_IVL
get/setHeartbeatLvl()
heartbeat interval
milliseconds between ZMPT PINGs
ZMQ_HEARTBEAT_TIMEOUT
get/setHeartbeatTimeout()
local heartbeat timeout
how long the local socket waits between received packets until it considers the connection timed out
ZMQ_HEARTBEAT_TTL
get/setHeartbeatTtl()
remote heartbeat timeout
if and when remote side shall consider the connection timed out
ZMQ_HEARTBEAT_CONTEXT is still in draft state as of 2022. It is supposed to send an byte[] context with every ping.
Now, by design of ZMQ, quoting from chapter 2 of its documentation,
The network connection itself happens in the background, and ZeroMQ
will automatically reconnect if the network connection is broken
(e.g., if the peer disappears and then comes back).
Thus, answering your main question, I'd expect the monitor to give you ZMQ_EVENT_CONNECT_RETRIED / ZMQ_EVENT_CONNECTED events after the underlying connection was detected as disrupted.

C#-Server / C++ Client: Socket.Accept() never finishes

I'm writing a simple C++ client that should connect to a C# server. And, while the client runs throught fine and even states it sent a bunch of bites, the C# server never gets past listener.Acceppt():
Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
I took the server source from here: Microsoft MSDN: Synchronous Server Socket Example
The client code I use can be found here: Microsoft MSDN: Complete Winsock Client Code
I also checked to server with the according C# client, which worked fine. I also checked the return values of the client, which also looked pretty plausible. So I'd guess the problem lies somewhere in how C++ / C# handle the details.
I tried Wireshark to find some hints, but mysteriously there was absolutely no trace of any communication on the used port (11000).
Where should I start looking to solve this issue?
Update: All communication at the moment runs just locally. I tried my IPAddress (from ipconfig) and 127.0.0.1 for both server and client.
I just have one network adapter installed, I use that IP adress. The client checks the getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result) and returns valid information (e.g. TCP as protocol). connect() returns 0, which should be ok.
Update 2:
I tried different combinations of C++/C# Server-Client-Setups:
C++-Server, C++ Client: Works
C++-Server, C# Client: Works
C#-Server, C# Client: Works
C#-Server, C++ Client: Does not work
C#-Server, putty: Works
Update 3: I tried Wireshark on the other Server-Client constellations, but neither of them did show any traffic on tcp.port == 11000, although they did work (see Update 2). It looks like Wireshark does not show any results, because everything is just local (see Wireshark localhost traffic capture)
I had the same problem.
The connection with winsock is asynchronous. And the example in C# that you are using is synchronous.
You have to use a Asynchronous example to get communication with your C++ code.
I used this two examples!
C Sharp server
https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.110).aspx
C plus plus client
https://msdn.microsoft.com/en-us/library/windows/desktop/ms737591(v=vs.85).aspx

Sockets stuck in Sent/Recv state

I recently stumbled across very strange bug. I first thought it was bug in my code, but right now I can see this is something system-wide, having said that, I think my problem fits SO best.
I was seeing very strange behavior of my network library and when I started debugging I discovered that if I will connect to a tcp socket, most often - soon after I started listening my sockets will get "stuck" in SYN_RCVD and SYN_SENT state. After even more debugging I dropped all my code altogether and I was left with this:
while (true)
{
TcpListener listener = new TcpListener(54000);
listener.Start();
var c = listener.AcceptTcpClientAsync();
TcpClient client = new TcpClient();
client.Connect(new IPEndPoint(IPAddress.Loopback, 54000));
c.Result.Close();
client.Close();
listener.Stop();
Console.WriteLine("done");
}
(classes above are System.Net.Sockets1s, not mine).
This code, on my machine will produce 1-5 dones and then will hang with 3 sockets: listening socket (bound to 0.0.0.0:54000 in listening state and 2 sockets, one stuck in SYN_RCVD, other one in SYN_SENT). I tried that on different machine, code runs ok, then I tried that on Linux VM on my 'broken' machine and it still does run ok.
Similar code in Node.js gets stuck as well.

Categories