TCP listener start exception in C# - c#

I create a TCP listener by using the code below:
TCPListener = new TcpListener(IPAddress.Any, 1234);
I start to listen TCP devices by using the code below:
TCPListener.Start();
But here, i don't control if the port is in use. When the port is in use, program gives an exception: "Only one usage of each socket address (protocol/network address/port) is normally permitted.".
How do i handle this exception? I want to warn user that the port is in use.

Put a try/catch block around TCPListener.Start(); and catch SocketException. Also if you are opening multiple connections from your program, then its better if you keep track of your connections in a list and before opening a connection see if you already have a connection opened

It's not a good idea to get an exception to check whether the port is in use or not. Use the IPGlobalProperties object to get to an array of TcpConnectionInformation objects, which you can then interrogate about endpoint IP and port.
int port = 1234; //<--- This is your value
bool isAvailable = true;
// Evaluate current system tcp connections. This is the same information provided
// by the netstat command line application, just in .Net strongly-typed object
// form. We will look through the list, and if our port we would like to use
// in our TcpClient is occupied, we will set isAvailable to false.
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
foreach (TcpConnectionInformation tcpi in tcpConnInfoArray)
{
if (tcpi.LocalEndPoint.Port==port)
{
isAvailable = false;
break;
}
}
// At this point, if isAvailable is true, we can proceed accordingly.
For details please read this.
For handling the exception you will use try/catch as habib suggested
try
{
TCPListener.Start();
}
catch(SocketException ex)
{
...
}

Catch it and display your own error message.
Check the exception type and use this type in catch clause.
try
{
TCPListener.Start();
}
catch(SocketException)
{
// Your handling goes here
}

Put it in a try catch block.
try {
TCPListener = new TcpListener(IPAddress.Any, 1234);
TCPListener.Start();
} catch (SocketException e) {
// Error handling routine
Console.WriteLine( e.ToString());
}

Use try-catch blocks and catch the SocketException.
try
{
//Code here
}
catch (SocketException ex)
{
//Handle exception here
}

Well, considering that you're talking about exceptional situation, just handle that exception with suitable try/catch block, and inform a user about a fact.

Related

Handle exception with a failed tcp connection in c# .NET

i'm trying to handle the exception of a failed tcp connection, but i don't know how exactly do it. I need it when it's impossible to connect to the server and i would a simple Message box that says the it's impossible to contact the server and than the program return to the main form.
public Connessione(string Hostname, int Port)
{
try
{
tcpSocket = new TcpClient(Hostname, Port);
}
catch
{
show the message box and go back to the main form
}
}
this is the part of the code. i would ask you also a good guide about how to handle exception. thank you so much!!
In the catch statement you can get the exception thrown like this (or anything similar):
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Also, if you do not catch the exception (or throw a new one), any code calling the Connessione method can catch the exception like this:
void FirstMethod()
{
try
{
Connessione("google.com", 80);
}
catch (Exception ex)
{
MessageBox.Show("Could not connect to server: " + ex.Message);
}
}
public void Connessione(string hostname, int port)
{
TcpClient tcpSocket = new TcpClient(hostname, port);
// ... Doing things with tcpSocket
}
This is a great article going through how exceptions work and how to use them properly:
https://stackify.com/csharp-exception-handling-best-practices/?utm_referrer=https%3A%2F%2Fduckduckgo.com%2F

How to Dispose a Socket after ConnectAsync times out? [duplicate]

I feel, that I am misunderstanding something about async sockets in .Net. The situation is as follows : I have 1 async socket client and 1 async socket server. They communicate without any visible problems, but when I close listener and disconnect clients, the "OnConnectRequest" which is bound to "BeginAccept" as a callback, still gets called at least once. The "BeginReceive", "OnConnectRequest", "Disconnect" and "Dispose" methods are :
public void BeginReceive()
{
_listener.Bind(_endpoint);
_listener.Listen(_maxConnections);
try
{
_listener.BeginAccept(new AsyncCallback(OnConnectRequest), _listener);
}
catch (SocketException se)
{
OnListeningError(this, new Exception("Server cannot accept connections due to network shutdown or some fatal failure", se));
}
}
protected void OnConnectRequest(IAsyncResult ar)
{
Socket listener = (Socket)ar.AsyncState;
Socket client = listener.EndAccept(ar);
var remoteEndpoint = client.RemoteEndPoint;
IDuplexStateObject state = new DuplexStateObject();
state.WorkSocket = client;
if (_clients.Count <= _maxConnections)
{
lock (_clients)
{
_clients.Add(state);
}
OnConnected(this, state);
}
else
{
//denying connection
client.Close();
AcceptingError(this, null, new Exception(string.Format("Maximal connection count reached, connection attempt {0} has been denied", (remoteEndpoint != null) ? remoteEndpoint.ToString() : null)));
}
//accept connections from other clients
try
{
listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
}
catch (SocketException se)
{
if (se.SocketErrorCode == SocketError.TooManyOpenSockets)
{
OnListeningError(this, new Exception("Maximal connection count reached, not possible to create any more connections"));
}
else
{
OnListeningError(this, new Exception("Server cannot accept connections due to network shutdown or some fatal failure"));
}
}
}
public void Disconnect(IStateObject state)
{
if (state.WorkSocket == null)
{
//OnDisconnectError(this, state.ClientInfo,
// new Exception("No underlying work socket found for client. Already disconnected, disposing connection..."));
OnDisconnected(this, state.ClientInfo);
return;
}
try
{
if (state.WorkSocket.Connected)
{
state.WorkSocket.Shutdown(SocketShutdown.Both);
}
state.WorkSocket.Close();
}
catch (SocketException se)
{
OnDisconnectError(this, state.ClientInfo, se);
}
OnDisconnected(this, state.ClientInfo);
lock (_clients)
{
_clients.Remove(state);
}
}
public void Dispose()
{
_listener.Close();
//keys are cloned before disconnecting
foreach (var client in _clients.ToList())
{
Disconnect(client);
}
}
What I am doing is calling "Dispose" to closes listener and shut down all client sockets. The client is then still active, and it tries to reconnect, but what I expected to happen was server being completely unavailable on corresponding IP and port. What I see instead is "OnConnectRequest" callback being called, which crashes because of attempt to use already disposed socket. Can you please explain, what is wrong here, and how graceful shutdown of a listener and all accepted connections should look like ?
No, this is correct -- the callback you specify in a Begin... operation will always be called, even if you close the socket (if you close the socket, it will be called because of that). You should be catching the ObjectDisposedException you get on the EndAccept and then return without further action. Closing/disposing a socket/listener is the only way to cancel an asynchronous operation on it. (EndAccept can also produce SocketException, which should be handled normally.)
Using a flag you maintain yourself to check if the listener is still available is asking for trouble, because you're introducing shared state that needs to be synchronized (volatile reads and the like). You can easily introduce race conditions that way. The listener already maintains such a flag for you internally, which it uses to throw ObjectDisposedException, so I'd just use that. It's true that under normal circumstances catching ObjectDisposedException is a possible sign of a coding error (since you're supposed to know when an object is disposed), but with asynchronous code it's pretty standard.

Get the actual socket from SocketException

How do I get the current socket from a SocketException?
I have a list of all available sockets and if the socket is no longer available I would like to remove it from the list.
try
{
/* Socket stuff */
}
catch (SocketException se)
{
if (ex.ErrorCode == (int)SocketError.ConnectionAborted)
{
// Remove socket from list
ConnectionAborted( currentSocket );
}
}
I have checked MSDN, but couldn't find anything.
So the method ConnectionAborted should remove the socket where the problem occurs from the list so it no longer check for new data.
A SocketException is thrown by the Socket and Dns classes when an error occurs with the network.
This means that one of the methods of Socket objects throws SocketException, therefore you already know its source and the code shpould be something like this:
Socket currentSocket;
try
{
/* Socket stuff with currentSocket */
}
catch (SocketException se)
{
if (ex.ErrorCode == (int)SocketError.ConnectionAborted)
{
//Remove socket from list
ConnectionAborted( currentSocket ); // At his point currentSocket is in scope.
}
}

Determine if a server is listening on a given port

I need to poll a server, which is running some propriatary software, to determine if this service is running. Using wireshark, I've been able to narrow down the TCP port its using, but it appears that the traffic is encrypted.
In my case, its a safe bet that if the server is accepting connections (i.e. telnet serverName 1234) the service is up and all is OK. In other words, I don't need do any actual data exchange, just open a connection and then safely close it.
I'm wondering how I can emulate this with C# and Sockets. My network programming basically ends with WebClient, so any help here is really appreciated.
The process is actually very simple.
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
try
{
socket.Connect(host, port);
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.ConnectionRefused)
{
// ...
}
}
}
Just use TcpClient try to connect to the server, TcpClient.Connect will throw an exception if the connection fails.
bool IsListening(string server, int port)
{
using(TcpClient client = new TcpClient())
{
try
{
client.Connect(server, port);
}
catch(SocketException)
{
return false;
}
client.Close();
return true;
}
}
I've used the following code. There is one caveat ... in a high transaction environment, the client's available ports may run out as the sockets are not released by the OS at the same rate they are released by the .NET code.
If anyone's got a better idea, please post. I've seen snowball issues arise where the server can no longer make outgoing connections. I'm working on a better solution ...
public static bool IsServerUp(string server, int port, int timeout)
{
bool isUp;
try
{
using (TcpClient tcp = new TcpClient())
{
IAsyncResult ar = tcp.BeginConnect(server, port, null, null);
WaitHandle wh = ar.AsyncWaitHandle;
try
{
if (!wh.WaitOne(TimeSpan.FromMilliseconds(timeout), false))
{
tcp.EndConnect(ar);
tcp.Close();
throw new SocketException();
}
isUp = true;
tcp.EndConnect(ar);
}
finally
{
wh.Close();
}
}
}
catch (SocketException e)
{
LOGGER.Warn(string.Format("TCP connection to server {0} failed.", server), e);
isUp = false;
}
return isUp;
Use the TcpClient class to connect the server.

Socket Programming

In simulation of a lan-messenger in c# I am using the loopback address just for starters to check the functionality of the code.However after sending a few messages, I am getting a socket exception while using the end-connect method and then a socket exception while sending the data. Is there any reason behind this exception.
private void button1_Click(object sender, EventArgs e)
{
HideCaret(this.textBox1.Handle);
StringBuilder sb = new StringBuilder(this.textBox1.Text);
str = this.textBox2.Text;
Socket newsock = new Socket(AddressFamily.InterNetwork,socketType.Stream, ProtocolType.Tcp);
IPEndPoint ip = new IPEndPoint(localaddress, 5555);
newsock.BeginConnect(ip, new AsyncCallback(connected), newsock);
if (str != "")
{
sb.AppendLine(this.textBox2.Text);
this.textBox1.Text = sb.ToString();
this.textBox2.Text = "\0";
send = Encoding.ASCII.GetBytes(str);
try
{
newsock.BeginSend(send, 0, send.Length, SocketFlags.None, new AsyncCallback(sent), newsock);
}
catch (ArgumentException)
{
MessageBox.Show("arguments incorrect in begin-send call", "Error", MessageBoxButtons.OK);
}
catch (SocketException)
{
MessageBox.Show("error in accessing socket while sending", "Error", MessageBoxButtons.OK);
}
catch (ObjectDisposedException)
{
MessageBox.Show("socket closed while sending", "Error", MessageBoxButtons.OK);
}
catch (Exception)
{
MessageBox.Show("error while sending", "Error", MessageBoxButtons.OK);
}
}
}
Please help
It's possibly because you're not waiting for the socket to be connected before sending data. You have two options:
Send the data asynchronously from your connected callback method.
Send the data synchronously by blocking this thread until connected.
You accomplish #1 by combining the data to send and the socket into a new class, then passing that as state in your call to BeginConnect. Then move your send code to the callback method.
You accomplish #2 by setting up a System.Threading.ManualResetEvent and calling WaitOne after BeginConnect. Then call EndConnect in your connected callback method, followed by a Set on your ManualResetEvent. Then proceed to send as you have above.
You'll also probably learn more if you find out what kind of SocketException you're getting.
From the MSDN Documentation:
If you receive a SocketException,
use the SocketException.ErrorCode
property to obtain the specific error
code. After you have obtained this
code, refer to the Windows Sockets
version 2 API error code documentation
in the MSDN library for a detailed
description of the error.
Do you have a separate thread reading from the socket? If not, your socket buffers are probably filling up.
You can also use .Net Socket.Connect method it will block your code until connection. So, you don't need to use ManualResetEvent and calling WaitOne. And you can further use other socket asynchronous methods too.

Categories

Resources