How to Check SMTP Server is up and running - c#

I am currently checking SMTP Server is up and running before sending mail using below code :
public static bool ValidateSMTPServer()
{
bool valid = false;
System.Net.Sockets.TcpClient smtpTest = new System.Net.Sockets.TcpClient();
try
{
smtpTest.Connect(ConfigurationManager.AppSettings["SMTPServerName"], Convert.ToInt32(ConfigurationManager.AppSettings["PortNumber"]));
return true;
}
catch
{
return valid;
}
finally
{
smtpTest.Close();
}
}
But the problem is it takes around 25 seconds to respond back if server is not running..which decrease my page performance. I do this on Click of button before sending mails.
Is there any better approach than this ? or i can do some changes to existing code.
And in case of server is not running it goes to catch part and i make my flag return false which means smtp is down..is there any way i can get the status code that server is not running...SMTPException is also i tried..if i use the same program breaks.
Any help is appreciated.

You can check in the background - and store that in a static variable. Do it in a loop and you avoid the wait.
The setup could be changed using a local SMTP Server to take them from a drop folder. Lots of pseudo negatives but at least you can send when the server is down / overloaded / starting. I personally prefer that. I used that way for ages - sadly MS slowly is retiring their SMTP service. It is great if a server can just drop emails in a folder and then they get sent over time.
In a larger setup the SMTPO servre should not be down because it is a cluster behind a load balancer ;)

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();
}

TCPClient & Sockets failing to connect to the Server

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.

Fastest way to "broadcast" to list of TCP clients

I'm currently writing a chat-server, bottom up, in C#.
It's like one single big room, with all the clients in, and then you can initiate private chats also. I've also laid the code out for future integration of multiple rooms (but not necessary right now).
It's been written mostly for fun, but also because I'm going to make a new chatsite for young people like myself, as there are no one left here in Denmark.
I've just tested it out with 170 clients (Written in Javascript with JQuery and a Flash bridge to socket connectivity). The response time on local network from a message being sent to it being delivered was less than 1 second. But now I'm considering what kind of performance I'm able to squeeze out of this.
I can see if I connect two clients and then 168 other, and write on client 2 and watch client 1, it comes up immediately on client 1. And the CPU usage and RAM usage shows no signs of server stress at all. It copes fine and I think it can scale to at least 1000 - 1500 without the slightest problem.
I have however noticed something, and that is if I open the 170 clients again and send a message on client 1 and watch on client 170, there is a log around 750 milliseconds or so.
I know the problem, and that is, when the server receives a chat message it broadcasts it to every client on the server. It does however need to enumerate all these clients, and that takes time. The delay right now is very acceptable for a chat, but I'm worried client 1 sending to client 750 maybe (not tested yet) will take 2 - 3 seconds. And i'm also worried when I begin to get maybe 2 - 3 messages a second.
So to sum it up, I want to speed up the server broadcasting process. I'm already utilizing a parallel foreach loop and I'm also using asynchronous sockets.
Here is the broadcasting code:
lock (_clientLock)
{
Parallel.ForEach(_clients, c =>
{
c.Value.Send(message);
});
}
And here is the send function being invoked on each client:
try {
byte[] bytesOut = System.Text.Encoding.UTF8.GetBytes(message + "\0");
_socket.BeginSend(bytesOut, 0, bytesOut.Length, SocketFlags.None, new AsyncCallback(OnSocketSent), null);
}
catch (Exception ex) { Drop(); }
I want to know if there is any way to speed this up?
I've considered writing some kind of helper class accepting messages in a que and then using maybe 20 threads or so, to split up the broadcasting list.
But I want to know YOUR opinions on this topic, I'm a student and I want to learn! (:
Btw. I like how you spot problems in your code when about to post to stack overflow. I've now made an overloaded function to accept a byte array from the server class when using broadcast, so the UTF-8 conversion only needs to happen once. Also to play it safe, the calculation of the byte array length only happens once now. See the updated version below.
But I'm still interested in ways of improving this even more!
Updated broadcast function:
lock (_clientLock)
{
byte[] bytesOut = System.Text.Encoding.UTF8.GetBytes(message + "\0");
int bytesOutLength = bytesOut.Length;
Parallel.ForEach(_clients, c =>
{
c.Value.Send(bytesOut, bytesOutLength);
});
}
Updated send function on client object:
public void Send(byte[] message, int length)
{
try
{
_socket.BeginSend(message, 0, length, SocketFlags.None, new AsyncCallback(OnSocketSent), null);
}
catch (Exception ex) { Drop(); }
}
~1s sounds really slow for a local network. Average LAN latency is 0.3ms. Is Nagle enabled or disabled? I'm guessing it is enabled... so: change that (Socket.NoDelay). That does mean you have to take responsibility for not writing to the socket in an overly-fragmented way, of course - so don't drip the message in character-by-character. Assemble the message to send (or better: multiple outstanding messages) in memory, and send it as a unit.

odd behavior with C# ftp client class

I found an ftp client class in c# over a year ago and have been using it in a process that uploads files on a nightly basis. A few days ago we started having a problem where it would time out. I'm not well versed in this so I'm not sure why it's doing this.
When the program starts uploading a file it checks to see if it's logged in and if not, it calls the login method. In that method is this block of code.
if (this.resultCode != 230)
{
this.sendCommand("PASS " + password);
if (!(this.resultCode == 230 || this.resultCode == 202))
{
this.cleanup();
throw new FtpException(this.result.Substring(4));
}
}
On the line that says this.sendCommand("PASS"... it goes into this code.
private void sendCommand(String command)
{
if (this.verboseDebugging) Debug.WriteLine(command, "FtpClient");
Byte[] cmdBytes = Encoding.ASCII.GetBytes((command + "\r\n").ToCharArray());
clientSocket.Send(cmdBytes, cmdBytes.Length, 0);
this.readResponse();
}
If I let the program run, it times out. However if I step through it into the sendCommand method it executes fine. Does anyone know why it would work fine when I step through it? Nothing on our end has changed and I've been told nothing on the client's end has changed so I'm stumped. Thanks.
Let it run in debug mode and when it freezes hit pause so you can see exactly what line it's hung up on.
If it starts the transfer - it'll not need to login again, unless the connection interrupts and your client tries to reconnect which will result in relogin.
I strongly suggest into looking if the client supports "NOOP" command (used to keep the control connection alive while the data is transferred over data connection). That's the most common problem with FTP implementations.

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