TCPClient & Sockets failing to connect to the Server - c#

I have a very strange problem with my connection to a server on a TCPListener/TCPClient basis. At some point during testing I am unable to connect to my server-application anymore, every try it times out. Netstats on both sides show, that my application listens on the right port, and the client is trying to connect to the right ip and port, but it does not advance further than "SYN_SENT". The server just displays "LISTENING" all the time. All I can do is restart my PC, which temporarily fixes this problem. But after some connections, it starts all over again.
Up to now I tested TCPClient and Sockets class to connect to the server but both show this behaviour, what is not surprising, as TCPClient is a wrapper around the Sockets Class afaik.
Firewall is checked on both sides, things like Remote Desktop work perfectly fine, and is not blocking the Connection of my Application. There are no connections left to close or something, already cheked everything I know (maybe not that much ;) )
So whats the problem?
Edit:
A Method that needs to connect to my Server:
public int GetSomeDataFromServer(string blargh)
{
int ret;
try
{
using(ConnectionTCPStream ctp = new ConnectionTCPStream())
{
if(ctp.EstSecConnWithServ())
{
ret = CKSHandler(ctp, blargh);
}
else
{ ret = (int)ErrFlags.ServerDeniedConnection; }
}
return ret;
}
catch(Exception)
{
InternalError = ErrFlags.ServerUnreachable;
return (int)ErrFlags.ServerUnreachable;
}
}
The Constructor of my Class that is dealing with the Connections:
public ConnectionTCPStream()
{
Client = new TcpClient("VeryImportantAdress", 49778); //it fails right here!
rsaCrypt = new RSACH() { RSAForeignPubKey = "An 8192-Bit long RSA Public key." };
AESPASS = AESThenHMAC.CreatePassword(200);
}

Sounds like you are using up all your connections or some other resource.
What do you see when you do a netstat -an ? Do you see a bunch of open ports?
There an Article Here that could possibly help you here
Some other resource may be killing you, might be worth having an SA fire up a resource monitor to check the health of the host when you run into this situation.
If there's no errors being thrown, it makes your life that much harder. The problem typically happens when you don't cleanly clean up your socket disconnects.

The answer is the firewall which changed its mind every now and then. I couldn't test that before because i had no access to it. Now i have changed settings while i had this blockade and it worked fine again. So the answer is: Always have access to the firewall and don't forget to check it.

Related

How to check PC is connected with Internet or Intranet without IP address and Ping method in C#?

How can I check PC is Connected with Intranet or Internet without using Ping method and IP address in C#?
For my use case, I needed to have a service up in a LAN network and check Network status from time to time. I eventually used this:
static readonly INetworkListManager NetworkListManager = new NetworkListManager();
// ...
while (NetworkListManager.IsConnected) {
// do something...
}
// loop is over. no internet!
while (!NetworkListManager.IsConnected) {
// wait for reconnection...
}
In my case that achieved what I needed, and with some testing it also worked on my WAN environment. But as always, there's no 100% correct assumption when it comes to interacting with other hardware. Incorrect result can happen, so put in as much as test you can.
Here's something i used for a game of mine to detect if there is a network connection without it even touching or talking the router or other devices:
// Recommended for clean code
public static bool InternetConnection() => System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
The code above is just the same as:
public static bool InternetConnection() {
return System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
}

Connecting to Multiple TCP Servers From Client C#

Making the properties TcpClient and IPEndPoint appear to have fixed my issue! If anyone could explain why this is the case I would appreciate it. I do usually declare my class objects static but I don't entirely understand why it works this way.
I'd like to start by saying the usual, I've googled and googled but haven't found anything answering my question so please point me if there is already an answer to this question.
I have written successfully a TCP server and client in C#, however I would like my client to be able to connect to multiple servers. To be clear this is not a server with multiple clients connected to it, I had no issues configuring that.
Here is a little picture explaining what I mean:
Pretty, I know. But in all seriousness I can't get this to work. I met with the error: A connect request was made on an already connected socket
I have a class called client, with a TcpClient and an IPEndPoint:
public Client(IPEndPoint ip)
{
client = new TcpClient();
this.ip = ip;
}
This class has methods connect, send, receive etc. The issue comes when I do something like this:
Client host = new Client(hosts.ElementAt(0));
IPEndPoint ipe = hosts.ElementAt(0);
EDIT: This contructor occurs in a different method than the method the "host" constructor does
Client client = new Client(ipe);
client.ConnectAsync();
host.ConnectAsync();
Now originally I tried to use the new async methods and the await feature, it worked fine when it was only one host but on the second it began to error. I thought perhaps it was becuase I was using the same method and it was attempting to connect before the first await had completed, it would try to connect again on the first IP, no idea if that makes any sense but basically I thought, well I will just create a new thread for each connect attempt like so:
public void ConnectAsync()
{
ThreadPool.QueueUserWorkItem(delegate { ConnectAsyncMethod(); });
}
private void ConnectAsyncMethod()
{
Thread connectThread = new Thread(() =>
{
try
{
client.Connect(ip.Address, ip.Port);
this.clientStream = client.GetStream();
ReceiveAsync();
}
catch (SocketException se)
{
}
catch (NotSupportedException ns)
{
}
catch (Exception e)
{
}
});
connectThread.Start();
}
Even though the connect is run on a new thread, I still get the same error, but why?
Could anyone point me towards a solution and hopefully explain where the flaws in my thinking lie? I am now thinking perhaps it is something in the way sockets are handled but I'm really not sure.
I appreciate any help, thank you everyone.
You will need multiple Client objects to establish multiple connections to different addresses (or the same in fact). For example, you could have a Client ClientA connect to Server A and have a Client ClientB connect to Server B. You cannot have the same Client object connect two times to diffrent or the same address.
This is strange.Maybe you would check whether the 2nd client port conflicts with the first client which will result in the error.
Here I found the official manual of this(10056):
http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa924071(v=vs.85).aspx

C# program hangs on Socket.Accept()

I created a server "middleman" application that uses sockets and multi-threading techniques (ServerListener is run in a new thread). I found early on that when I would use the Socket.Accept() method, the program would hang indefinitely, waiting for that connection to happen. The problem is, as far as I can tell there is no reason for it not to.
I spent a good portion of the day trying lots of different things to make it work, and somewhere something changed because it suddenly started working for a while. However, as soon as I accidentally chose a different data source than "localhost" for the client application, the problem popped back up again. I have tried running the program without the firewall OR antivirus running, but no luck. The client program IS set to connect on port 10000. Here is my code:
public void ServerListener() {
UpdateStatus("Establishing link to server");
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(new IPEndPoint(IPAddress.Any, defaultPort));
server.Listen(queue);
UpdateStatus("Accepting Connections");
while (true) {
Socket client = default(Socket);
try {
client = server.Accept();
if (client != null) {
++count;
UpdateCount(count.ToString());
new Thread(
() => {
Client myclient = new Client(client, defaultPort, this);
}
).Start();
}
}
catch( Exception ex ){
MessageBox.Show(ex.ToString());
client.Close();
}
}
}
It will run just fine right up until server.Accept(), then hangs. As stated, it did work for a while earlier, but is now hanging again. I've tried to see if any other programs are using port 10000, and they aren't. I went over and over this with a friend, and we couldn't find the problem. Please help!
EDIT To be clear, I do know that Accept is a blocking call. The client program makes the connection on port 10000, but this program keeps on waiting on the Accept as if nothing happened. It did work for a time, so I know the connection is working like it is supposed to from the client program's end. However, I can't fathom why this program is now acting like that connection never happens, and continues to wait on the Accept.
Accept blocks on purpose. If you want to do other things while waiting for another client to connect you can:
Run the ServerListener in another Thread or better - a long running task:
using System.Threading.Tasks;
...
Task.Factory.StartNew(ServerListener, TaskCreationOptions.LongRunning);
Use the AcceptAsync method which uses the SocketAsyncEventArgs class. For that to work, you create a new SocketAsyncEventArgs instance, set its values and pass it to socket.AcceptAsync.

Determine if internet connection is available

I know that I am not the first to ask the question: How do I find out if my application is online or not?
I found this post: StackOverflow.
I want to do it with C# and .NET 3.5.
The recommendation is to ping the resource regularly. I am not very happy with that advice. I would rather detect a network change and THEN ping my service to check if it is online.
.NET provides two events for this purpose:
NetworkChange.NetworkAvailabilityChanged
NetworkChange.NetworkAddressChanged
The first event sounds good but it is fired only if the last network card which is online goes offline. I have several virtual network cards which have been installed by VMWare and those are always online.
The second event works but between plugging the network cable and the event, there are often 5 seconds wait time.
The Windows tray icon reacts more or less immediately when I am unplugging the cable.
What is the best way to be as fast as this tray icon?
My workaround would be to poll
NetworkInterface.GetAllNetworkInterfaces()
every 500ms and to throw my own event in case that the status of a network adapter changed.
There must be a better solution :)
I tried the link the Webleeuw suggested, but that code also needs between 4 and 10 seconds to notify me when I plug or unplug my cable.
Now, I wanted to know if it just my computer or installation and I wrote my own Observer class which is based on NetworkInterface.GetAllNetworkInterfaces().
And: It works with lightning speed. My app reacts now as quickly as does the tray.
The code is far from production code, it is just a quick hack. But this is what I will build upon now :)
using System;
using System.Net.NetworkInformation;
using Timer=System.Threading.Timer;
namespace NetworkCheckApp
{
public class NetworkStatusObserver
{
public event EventHandler<EventArgs> NetworkChanged;
private NetworkInterface[] oldInterfaces;
private Timer timer;
public void Start()
{
timer = new Timer(UpdateNetworkStatus, null, new TimeSpan(0, 0, 0, 0, 500), new TimeSpan(0, 0, 0, 0, 500));
oldInterfaces = NetworkInterface.GetAllNetworkInterfaces();
}
private void UpdateNetworkStatus(object o)
{
var newInterfaces = NetworkInterface.GetAllNetworkInterfaces();
bool hasChanges = false;
if (newInterfaces.Length != oldInterfaces.Length)
{
hasChanges = true;
}
if (!hasChanges)
{
for (int i = 0; i < oldInterfaces.Length; i++)
{
if (oldInterfaces[i].Name != newInterfaces[i].Name || oldInterfaces[i].OperationalStatus != newInterfaces[i].OperationalStatus)
{
hasChanges = true;
break;
}
}
}
oldInterfaces = newInterfaces;
if (hasChanges)
{
RaiseNetworkChanged();
}
}
private void RaiseNetworkChanged()
{
if (NetworkChanged != null)
{
NetworkChanged.Invoke(this, null);
}
}
}
}
Try this using NetworkChange class
using System.Net.NetworkInformation
private void Form5_Load(object sender, EventArgs e)
{
NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
}
private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
if (e.IsAvailable)
{
MessageBox.Show("Available");
}
else
{
MessageBox.Show("Not available");
}
}
People here already told it but there is a diference between network availability and internet availability.
You can have network availability between your network interface and local router but havent internet availability between your local router and your Internet Service Provider (ISP).
There is another problem that testing by ping will tell you about internet availability but not about what network interface is providing it, i think the only way is force ping throught one interface but it isnot possible on windows.
Pinging your resource regularly is the only option that will give you a notification if the service goes offline, as well as if the client goes offline. Potentially you want to handle both situations.
The windows tray icon is very likely connected to the network card drivers, i.e. below the operating system level which is why it can react so fast.
Since the network card is only one of many links between your client and the service that it accesses on the Internet, the only reliable way to detect whether or not the Internet is available is to poll some service out on the Internet, much the same way that ping does. In TCP/IP networking, this is known as a keepalive, and many protocols will have this built into them as an option.
About the pinging: depending on how you wish to interpret the results, pinging doesn't seem watertight to me. What if the target times out once in a while, while the connection remains alive? I have yet to see the server that never fails to respond to a ping.
Checking every X millis if the network interface is still online (NetworkInterface.OperationalStatus property) seems more reliable if you'd ask me.
EDIT: This article deals with network address events on a lower level than the System.Net.NetworkInformation.NetworkChange class, or so it seems. On my pc it works very fast, so hopefully you'll be able to use that solution.
You can use ping, but I would also build a simple call to return a "yes" if it is online. That way you do know if the server is up and that it is running your code. Also I would only call or ping when a network resource is needed and not continually.
Doing a ping is definitely not the cleanest option, especially if it is a web server. Some hosts will disable response to ICMP traffic, so you may ping but not get a response. How about just handling the exception gracefully when it occurs?

Is it possible to create an event and handle it, if the connection to a MySQL server is lost?

Let's say I have my client application and it makes a connection to the MySQL server. Fantastic. I don't implement this as a thread. I just utilise the MySQLConnection class.
And now let's say Jim who's really careless about the office accidently reboots the MySQL server without asking permission first.
I want to know when the disconnection happens so the client application is aware and the user doesn't get a lot of errors.
I can think of a few ways to check this but I don't know if they'll work and even if they're elegant in design. I was wondering what you folks thought was the most appropriate way.
Implement the connection as a thread and check it every x seconds (if it's even possible)
Create and handle an event when the connection drops (sort of relies on the point above)
Maybe there's a event built into the MySQL Connector library that I'm not even aware of
Some other mystical dark code that I'm not aware of
Any help is very much appreciated.
Edit: This question has been answered in comments. Thanks for reading.
I have an "occasionally connected" application and faced this problem. I needed to know if the user had a network connection and, if they did, if they had a VPN connection that would allow them to connect to the SQL Server database. I used a timer to ping the database server once a minute to check its reachability.
public NetworkStatus GetNetworkStatus()
{
NetworkStatus netStatus = new NetworkStatus();
netStatus.NetworkAvailable = NetworkInterface.GetIsNetworkAvailable();
try
{
if (netStatus.NetworkAvailable)
{
Ping p = new Ping();
// Create a buffer of 32 bytes of data to be transmitted.
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
PingReply reply = p.Send(DB_SERVER_NAME, 1200, buffer);
netStatus.PublisherPingSuccess = reply.Status == IPStatus.Success;
}
}
catch (Exception ex)
{
netStatus.PublisherPingSuccess = false;
netStatus.Error = ex;
}
return netStatus;
}

Categories