I plan to write an application using sockets in C# and started by following Microsoft's own examples at https://learn.microsoft.com/en-us/dotnet/framework/network-programming/socket-code-examples but I am running into problems making them communicate.
I used the Asynchronous Server and Asynchronous Client examples there, pasting the example code into .net console apps in Visual Studio 2019. My only change in the code was to change the server address in the client program as appropriate. The client should open a socket to the server on port 11000, send a short test string, which the server returns to the client, with both sides giving console output when successful. If I run both client and server on the same Windows 10 machine the example works correctly (with client set to connect via 127.0.0.1).
If I run the client on a separate Windows 10 machine it cannot connect to the server. No console output appears on the server that would normally indicate a connection, and a breakpoint set in the server example where the connection is first made is never hit. The two machines communicate normally for other tasks, e.g. Windows network shares function correctly between them.
I have tried disabling the Windows firewall on both server and client machines, and (following another thread's suggestion) running Visual Studio as administrator, with no change in outcome. I have used NETSTAT on the server to verify that no other process is trying to use port 11000, and I have tried using alternate ports.
On the client side the program shows the following:
System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (10060): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 192.168.1.107:11000
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source)
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
at AsynchronousClient.ConnectCallback(IAsyncResult ar) in C:\Users\dunca\source\repos\ConsoleClient1\Program.cs:line 87
I have run Wireshark on the server side machine to try to see what's happening, using a filter on Wireshark to only show communication between the client and server IP addresses.
[CLIENT_IP] [SERVER_IP] TCP 66 59959 → 11000 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
[CLIENT_IP] [SERVER_IP] TCP 66 [TCP Retransmission] 59959 → 11000 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
[CLIENT_IP] [SERVER_IP] TCP 66 [TCP Retransmission] 59959 → 11000 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
[CLIENT_IP] [SERVER_IP] TCP 66 [TCP Retransmission] 59959 → 11000 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
Wireshark on the client machine shows the same but with source and destination IP addresses reversed. It appears that no ACK is going back to the client, though Wireshark only sees what passes through the network card so it's possible that the server is generating a response but it is being blocked on the outgoing side of the server machine. However, as I said the firewall was completely disabled (for private networks) on both machines.
I'm stumped on what to try next, but suspect it may still be a Windows/Firewall issue since it works with client and server running on the same machine.
Edit:
As I am working from home the server machine is using a VPN to connect to my normal workplace, and I suspected some interference from this. I disconnected the VPN and completely disabled the Windows firewall before retrying the experiment, with different results. The client machine now reports that the connection was "actively refused", while Wireshark on the server reports the following...
[CLIENT_IP] [SERVER_IP] TCP 66 52067 → 11000 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
[CLIENT_IP] [SERVER_IP] TCP 54 11000 → 52067 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
Yes, [RST, ACK] or "I heard you and I am closing this connection."
EDIT-EDIT: Solved this, server program was binding to the wrong network adapter as it assumes the first available will be correct.
The server was binding to the wrong network interface. Dns.GetHostEntry() returns an array of network interfaces, but Microsoft's example code blindly selects the first in the list. If I pick the correct one (local network) then everything works between two machines.