TcpListener.AcceptSocketAsync issues in Windows 7 - c#

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!

Related

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.

Windows Time change causes TcpClient timed out

In our c# application, we are using a TcpClient listening for messages coming from our clients.
When the connection is established we set a time out on the socket, to avoid to have useless open connections.
We encountered a strange behaviour when we change the Windows Time to a future time.
Just to be clear.
Socket Timeout set to 30seconds.
Starting situation: Windows Time = 10:00:00 (UTC)
We manually change time to 10:01:00(UTC)
Immediately we got the Socket timedout.
Is this a normal behaviour in Windows or something bad is happening in our implementation?
System references:
Windows 7 x64
.Net 4.5
Edit:
We set the TimeOut in this way:
TcpClient tcpClient = TcpConnectionListener.AcceptTcpClient();
tcpClient.ReceiveTimeout = RECEIVE_TIMEOUT;
We expected that internally the TcpClient was using a Timer or something like that and not using the Windows Clock. Is this right?

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.

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

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).

Problem about checking a WCF connection is opened

I have a problem about checking a WCF connection is opened. My WCF Connection is bi-directional. I use State property to check the connection's state at client. My function:
private bool ConnectionIsOpen()
{
if (m_Service != null && (m_Service.State | CommunicationState.Opened) == CommunicationState.Opened)
{
return true;
}
return false;
}
I create a service which is a thread running every 10 seconds to check the connection's state. I use the method ConnectionIsOpen() for checking. Everything is well on running on Windows XP. However there is a problem when running on Windows 7.
When I unplug the network cable to create to disconnect, If running application on Windows XP, checking connection's State is Faulted but if running on Windows 7, checking connection' State is still Opened.
Anyone can help me how to check a connection is openned or not in this case. Thanks.
This will always be true:
(m_Service.State | CommunicationState.Opened) == CommunicationState.Opened
Example, m_Service.State = 0:
0 | CommuncationState.Opened == CommuncationState.Opened
You want to use & (AND) instead.
We ran into a similar problem in our own system; disconnecting the network cable or placing either the client machine or the server in sleep mode does not generate a channel fault.
From what I can tell, it seems that the connection state only indicates the state of the connection after the last call and not the current connection state. The only way to know the current state is to actually call the service.
If your client doesn’t need to call the service that often but must react if the connection is lost one solution is to implement a dummy call on the client side which periodically polls the service. If the connection is unavailable when the dummy call is made you’ll get a channel fault that you can then deal with.
The catch is you can’t simply use the dummy call to guarantee that the next call to the service will work:
public void SomeMethode()
{
if (ConnectionIsOpen())
{
m_Service.Dummy();
// Connection is lost here
m_Service.SomeMethode();
}
}
To get around this problem, we implemented a system that automatically re-executes any failed service calls which generate a channel fault after the connection has been restored.
The best and asured way to confirm the Communication state is Open or not is to call the Faulted event like below :
proxyInstance.InnerChannel.Faulted -= new EventHandler(ProxyChannelFaulted);
But this works only with those bindings that support ReliableMessaging like WsHttpBinding.
For detail refer the link : WCF Proxy Client taking time to create, any cache or singleton solution for it
Thanks,
Jai Kumar
The fact that you are getting completely different results on windows 7 is not surprising. Microsoft completely re-engineered the TCP stack with windows vista, so the functionality is quite different from xp in the core networking functionality.
The first thing that I would do is use wireshark to see what is actually going across the wire. See if your TCP connection actually terminates when you pull the plug. Windows might be doing some kind of connection persistence / buffering in case the connection comes back quickly.

Categories