C# program hangs on Socket.Accept() - c#

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.

Related

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

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.

Closing of TCP socket - What is different when connection is closed by debugger

I create a socket connection to a PLC:
IPEndPoint endPoint = new IPEndPoint(plcAddress, PORT);
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_socket.Connect(endPoint);
m_stream = new NetworkStream(m_socket);
m_writer = new StreamWriter(m_stream);
m_reader = new StreamReader(m_stream);
When I close my program or the user clicks on logout then I call this code:
if (m_reader != null) m_reader.Close();
if (m_writer != null) m_writer.Close();
if (m_stream != null) m_stream.Close();
if (m_socket != null)
{
m_socket.Shutdown(SocketShutdown.Both);
m_socket.Disconnect(false);
m_socket.Close();
m_socket.Dispose();
m_socket = null;
}
But the PLC does not realize that the connection was closed. I cannot change any code on the PLC.
But when I stop the VisualStudio debugger (Shift+F5) while the connection is active, it is closed correctly. What is VisualStudio doing differently?
Edit:
These 2 lines are captured by wireshark additionally when I stop the program by Shift+F5
Edit 2:
I have a thread that reads data:
while (m_runListener)
{
int cnt = m_reader.Read(buffer, 0, 1024);
if (cnt > 0)
{
// handle data
}
}
When I close the program, I cannot stop the thread without calling Thread.Abort();
If I delete the blocking call m_reader.Read(buffer, 0, 1024); just for testing, the disconnect works.
I had a very similar issue recently and I also found that debugging through Visual Studio made the issue go away too. I believe this is due to the extra time it takes for the debugger in Visual Studio to do things, coupled with break points that obviously stop code execution that you may have in your closing code.
My rather nasty work around was to put Thread.Sleep(xxxx) calls between some of the closing code. I had one after the Shutdown and Disconnect calls to allow these processes to finish. I tried different values, but I settled with 100ms as that made sure the issue never occurred again.
Obviously a better way would be to see if you could put those calls into an asynchronous method and only call the next when the first is done, but I didn't bother due to the small size of the project and little use it will get.
However, I could be completely wrong and this isn't the issue you are having, it just sounds very similar to the issue I had a few weeks ago.
I finally found the solution to my problem here:
http://sysperf.yingyuhsieh.com/2007/08/force-tcp-closed-by-sending-rst-c.html
Normally the TCP connection is closed as follows:
The client sends FIN to the server and the server responds with ACK
The server sends FIN to the client and the client responds with ACK
In my case the second step was missing.
I needed to force that a RST packet was sent. This can be done by the following code:
m_socket.Send(new byte[1]);
m_socket.Shutdown(SocketShutdown.Receive);

C#: System.Net.Sockets.TcpListener is sometimes not closing Socket properly

in one of my projects I have implemented a small HTTP server to stream the video data of a connected webcam. For this task I'm utilizing the System.Net.Sockets.TcpListener from .NET Framework 4.5, which listens to a pre-configured endpoint and uses the AcceptSocketAsync() mtehod to wait for incomming requests. You can see the relevant code parts below:
this.server = new TcpListener(endpoint);
this.server.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, 0));
this.server.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
this.server.Start();
...
this.listenTask = Task.Factory.StartNew(this.Listen);
...
private async void Listen()
{
try
{
while (this.server.Server.IsBound)
{
Socket socket = await this.server.AcceptSocketAsync();
if (socket == null)
{
break;
}
Task.Factory.StartNew(() => this.ClientThread(socket));
}
}
catch (ObjectDisposedException)
{
Log.Debug("Media HttpServer closed.");
}
}
This works fine, when I start the application and the HTTP server is started for the first time. However, when I stop the HTTP server (done via CheckBox in the settings of the application) the unverlying listening socket is sometimes not closed. When I check for the state of the sockets via console (netstat -ano) I can see that the socket is still in state LISTENING. The resulting problem is, when I restart the HTTP server again I get an System.Net.Sockets.SocketException with the message "Only one usage of each socket address is normally permitted", which is not surprising.
The relevant code part for stopping the HTTP server is as follows:
...
if (this.server != null)
{
if (this.server.Server != null)
{
if (this.server.Server.Connected)
{
this.server.Server.Shutdown(SocketShutdown.Both);
this.server.Server.Disconnect(true);
}
this.server.Server.Close();
}
this.server.Stop();
}
...
I also keep track of my open connections and close them after finishing the transmission of data and when stopping the server. None of the connection sockets stays opened, so I believe only the listening socket should be relevant for this problem.
I already tried various combinations/orders of the Shutdown(), Disconnect(), Close() and Stop() methods when stopping the server, as well as setting/unsetting several options when starting the server like Linger and ReuseAddress, which sometimes seemed to fix the problem at first, but then a few days later the problem occurred again.
I also tried to "force" the listening socket to close when stopping the server using GetTcpTable(...) and SetTcpEntry(...) from iphlpapi.dll, as described in this question: How to close a TCP connection by port?
Unfortunately, this approach did not work for me (it change anything about the state of the listening socket at all).
As I'm a little bit clueless of what else I could do, I'm asking here if somebody has an idea of what might cause the discribed problem or how to solve it. Any help would be greatly appreciated.
Kind regards,
Chris
You should almost always leave TcpListener.Server alone. It's there so you can set socket options on it, not use it for control purposes.
So your Listen should be:
private async void Listen()
{
try
{
while (true)
{
Socket socket = await this.server.AcceptSocketAsync();
if (socket == null)
{
break;
}
Task.Run(() => this.ClientThread(socket));
}
}
catch (ObjectDisposedException)
{
Log.Debug("Media HttpServer closed.");
}
}
(assuming you do actually want one thread per client, an architecture I do not recommend in general).
When you're ready to stop, just stop:
if (this.server != null)
{
this.server.Stop();
}
If you do not have any special requirement, it is suggested to make use of TcpListener class and its methods only or if you have such requirement, do not use TcpListener and start with the Raw socket.
TcpListener class is self sufficient to provide method like
Start(), AcceptTcpClient() and Stop().
You can create a List<TcpClient> and loop through each client and call client.close() after calling Stop() on the TcpListener instance.
A very good example of client server communication is on MSDN:
http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener(v=vs.110).aspx
Regards
On server socket, shutdown & disconnect is not needed for listening sockets. Those calls are needed only for connected sockets. Replace the socket stop with below code:
if (this.server != null)
{
if (this.server.Server != null)
{
this.server.Server.Close();
this.server.Server = NULL;
}
}
I would dispose of your socket connections once you have closed them. The documentation says they should be disposed after closed but personally I like to say when to dispose of anything that use the IDisposable interface.

How can I unbind a socket in C#?

I'm having some problems reusing a server socket in a test application I've made. Basically, I have a program that implements both the client side and the server side. I run two instances of this program for testing purposes, one instance starts to host and the other connects. This is the listening code:
private void Listen_Click(object sender, EventArgs e)
{
try
{
server = new ConnectionWrapper();
HideControls();
alreadyReset = false;
int port = int.Parse(PortHostEdit.Text);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, port);
server.connection.Bind(iep); // bellow explanations refer to this line in particular
server.connection.Listen(1);
server.connection.BeginAccept(new AsyncCallback(OnClientConnected), null);
GameStatus.Text = "Waiting for connections on port " + port.ToString();
}
catch (Exception ex)
{
DispatchError(ex);
}
}
private void OnClientConnected(IAsyncResult iar)
{
try
{
me = Player.XPlayer;
myTurn = true;
server.connection = server.connection.EndAccept(iar); // I will only have one client, so I don't care for the original listening socket.
GameStatus.Text = server.connection.RemoteEndPoint.ToString() + " connected";
StartServerReceive();
}
catch (Exception ex)
{
DispatchError(ex);
}
}
This works fine the first time. However, after a while (when my little game ends), I call Dispose() on the server object, implemented like this:
public void Dispose()
{
connection.Close(); // connection is the actual socket
commandBuff.Clear(); // this is just a StringBuilder
}
I also have this in the object constructor:
public ConnectionWrapper()
{
commandBuff = new StringBuilder();
connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connection.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
I get no error when I click the Listen button a second time. The client side connects just fine, however my server side does not detect the client connection a second time, which basically renders the server useless anyway. I'm guessing it's connecting to the old, lingering socket, but I have no idea why this is happening to be honest. Here's the client connection code:
private void Connect_Click(object sender, EventArgs e)
{
try
{
client = new ConnectionWrapper();
HideControls();
alreadyReset = false;
IPAddress ip = IPAddress.Parse(IPEdit.Text);
int port = int.Parse(PortConnEdit.Text);
IPEndPoint ipe = new IPEndPoint(ip, port);
client.connection.BeginConnect(ipe, new AsyncCallback(OnConnectedToServer), null);
}
catch (Exception ex)
{
DispatchError(ex);
}
}
If I do netstat -a in CMD, I see that the port I use is still bound and its state is LISTENING, even after calling Dispose(). I read that this is normal, and that there's a timeout for that port to be "unbound".
Is there a way I can force that port to unbind or set a very short timeout until it automatically gets unbound? Right now, it only gets unbound when I exit the program. Maybe I'm doing something wrong in my server? If so, what could that be? Why does the client connect fine, yet the server side doesn't detect it a second time?
I could make the socket always listen, not dispose it, and use a separate socket to handle the server connection, which would probably fix it, but I want other programs to be able to use the port between successive play sessions.
I remember seeing another question asking this, but there was no satisfactory answer for my case there.
There may be a couple of reasons why the port would stay open, but I think you should be able to resolve your issue by using an explicit LingerOption on the socket:
LingerOption lo = new LingerOption(false, 0);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo);
This basically turns the socket shutdown into an abortive shutdown instead of a graceful shutdown. If you want it to be graceful but just not wait as long, then use true in the constructor and specify a small but nonzero value for the timeout.
I just noticed this line, which is almost undoubtedly part of your problem:
server.connection = server.connection.EndAccept(iar); // I will only have one client, so I don't care for the original listening socket.
The comment you've written here is, well, wrong. Your wrapper class really shouldn't allow connection to be written to at all. But you cannot simply replace the listening socket with the client socket - they're two different sockets!
What's going to happen here is that (a) the listening socket goes out of scope and therefore never gets explicitly closed/disposed - this will happen at a random time, possibly at a nasty time. And (b) the socket that you do close is just the client socket, it will not close the listening socket, and so it's no wonder that you're having trouble rebinding another listening socket.
What you're actually witnessing isn't a socket timeout, it's the time it takes for the garbage collector to realize that the listening socket is dead and free/finalize it. To fix this, you need to stop overwriting the listening socket; the Dispose method of your wrapper class should dispose the original listening socket, and the client socket should be tracked separately and disposed whenever you are actually done with it.
In fact, you should really never need to rebind another listening socket at all. The listening socket stays alive the whole time. The actual connection is represented by just the client socket. You should only need to dispose the listening socket when you finally shut down the server.
I agree with the previous answer, you should also "shutdown" to allow any existing activity to complete and then close the socket flagging it for reuse...
socket.Shutdown(SocketShutdown.Both);
socket.Disconnect(true);

Categories