What I have:
I have two socket client programs written in C#.
I have one socket server program (not written by me but it works) in Python.
The problem:
The first c# socket client I wrote works fine and can communicate with the python server client. I can send data over with no issue. However I wanted to rewrite the code to make it more object oriented, so I made the second program which is the same as the first in terms of what is done.
The issue is the second one won't connect, saying this:
System.Net.Sockets.SocketException: An attempt was made to access a socket in a forbidden way by its access permissions.
I googled this and I have come to the realization that the connection from the first connection hasn't been completely unbound.
When I did a netstat -a, I actually saw the connection and it said TIME_WAIT at the end.
The question is, how do I unbind it? Is it on the C#/client side?
FYI I have already tried closing/disconnecting/shutting down the socket and none of that worked. I also put in this command
connection.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
upon instantiation of the socket connection but that did not work either.
Would I have to do something on the server side to unbind the connection?
I know you said you already calling close or disconnect.
But are you reinitializing the socket variable.
eg: connection = new System.Net.Sockets.Socket(...
If you are using an older version of .Net you may also have to call Dispose() after call Close().
eg:
connection.Close();
connection.Dispose();
connection = new System.Net.Sockets.Socket(...
Be sure to always work with sockets within try statements as any calls to send and receive data or close the socket could result it an error at which stage, you should log the error and call Close() and then if applicable Dispose() on the socket instance to clear the resources. Once this has been done, you can then reinitialize a new instance of the socket to attempt a new connection to the server.
Related
I have basically implemented this asynchronous server socket example (and the corresponding client). Using it, I can respond to the client if I follow the example exactly, i.e., if the call to Send() the response is in the ReadCallback() method.
If, however, I try and send a response outside of here, i.e., in a callback that I've attached to my message processing routine (running in a different thread), I get this error, saying the Socket is not connected. If I try and send a response somewhere else in the Server code, say in the while(true) loop that's listening to incoming connections, I get the same error.
Am I missing something fundamental here?
Edit:
Ok, so I read Two-way communication in socket programming using C, and I now think, according to that answer, that I have to modify the example I linked to so that I reply to the server on the socket returned by the accept process. My goal is to be able to call Send() outside of the receive callback, say from Main(), after the client and server are connected.
Please can someone suggest how I modify the example to achieve what I want? I'm getting thoroughly confused about this, and don't want to create a separate stream if I don't need to (which according to the question I posted, I don't need to...).
If you want to keep the connection open then would need to persist the handler variable as that is the open socket connection. Then whenever you want to send that connection a message you retrieve its socket and send.
Also, you obviously wouldn't call Shutdown() and Close() on the handler variable.
Edit: Yes I know that UDP doesn't technically connect, but you can still use it to set the default target for Send(), which is what I'm doing here.
Basically I have this problem that between calls to MySocket.Send(), MySocket is becoming disconnected i.e. the Connected variable becomes false (I know that Connected isn't necessarily up-to-date, but no data isn't being sent so I know that it's telling the truth).
The strange thing is that the RemoteEndPoint variable is still set correctly, but when I call Send(), no data is recieved by the other computer. However if I call Connect() again, the socket does connect, and I'm able to send data (at least until the next time the user does something that causes another call to Send() )
Can anyone tell me why a socket would spontaneously disconnect?
The line where I connect it is:
opep = new IPEndPoint(Opponent.Address, 1000);
Listener.Connect(opep);
I don't see anything here that could be garbage collected for example to cause this issue.
Thanks!
UDP doesn't set up a connection. You should check out the following link for more info
Difference between TCP and UDP?
I have an TCP asynchronous project and there's a problem when it comes to reconnect the client to the server if the connection was closed.(wasn't closed by the server).
When the server is closed the client gets the following error :
An existing connection was forcibly closed by the remote host at EndReceive(IAyncResult ar) at ReceiveCallback(IAsyncResult ar)
PS:The client can only receive streams from the server.
Things being said , I understand that I need somehow to reconnect to the server .
I have tried to do something but it didn't worked because the client was not responding and exiting.
What I did was , in the catch block of the Receiving callback which contains the steps below , I set the ClientSocket to Disconnected(true) and in a while loop (!ClientSocket.Connected) , I was recalling the main method which starts the asynchronous operation again and the last line of code was Thread.Sleep(n);
These things are done in the receive callback
Getting the string from the buffer
Doing whatever.. with the string
Calling again BeginReceive
PS: I don't want to use another port.
You must catch that exception (you can look for specific error code) and then close that socket and get rid of it. Then create a new one from scratch.
this is my first post here so please be gentle =)
I'm writing an asynchronuos server/client application for the management of a DB for my office, i tested it locally on my computer and it worked fine. When I uploaded the server tool on another machine I found something that is driving me crazy: the server/client handle only the first query, when I send another query both server and client crash.
After going through lines in debug mode I found the problem: after the beginconnect() (during the second query) the socket is connected but when the debugger reaches the beginsend() line the socket is disconnected (this happens only on client side, the socket on server side seems connected).
I can't figure how it can happen, the socket is re-instantiated every time I send a new query and of course is shutted down and disposed after the query process (send/receive) is completed. My idea is that the disposal of the socket doesn't happen immediately but after a while (but why always between the new beginconnect() and beginsend()?). Do you have any clue on this? Or I should reserve a room in a mental hospital?
* NEW PART (EDITED) *
well..here again! This time the socket on client side remains open for the entire session (socket closure occurs only on client tool closure) but i receive another kind of error: "System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)"
After some googling I discovered that this kind of error is generally triggered by the server on the other side of the connection so I tryed to "mine" server code lines to figure where this connection closure command is. I found that the problem may be in the following piece of code:
private static void SendCallback(IAsyncResult ar)
{
Console.WriteLine("send callback");
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("\nQuery answer sent to client");
handler.Shutdown(SocketShutdown.Both);
//handler.Disconnect(true);
//handler.Dispose();
state.content = new List<byte[]>();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey();
}
}
deleting the handler.shutdown line the client is no more able to detect the end of transmission (not a real problem, is the last part of the sent packet so it is possible to use that as trigger..at least I think). Any suggestion? I read something about the keepalive but I can't understand how to set it and if it is really necessary in this situation. Thanks in advance for all your effort.
I would recommend not to open and close sockets like you do.Keep a socket open if possible, because it needs to get freed by your program and the OS.
What is the correct way to close or reset a TcpClient connection?
We have software that communicates with hardware but sometimes something
goes wrong and we are no longer to communicate with it, until we restart the software.
I have tried forcing TcpClient.Close() and even setting it to null but that doesn't work.
Only a complete restart of the software works.
Suggestions?
I can't use the using keyword because TpcClient is only defined in one location, but used throughout the library. (And there is only one connection at any given time)
It's a library that handles communication. The software itself can call the ResetConnection() method of the Controller class (which represents the hardware).
It currently looks like
if (tcpClient != null)
{
tcpClient.Close();
tcpClient = null;
}
Now from what I've read here I should use tcpClient.Dispose() instead of " = null"
I'll give that a try and see if it makes a difference.
You have to close the stream before closing the connection:
tcpClient.GetStream().Close();
tcpClient.Close();
Closing the client does not close the stream.
Given that the accepted answer is outdated and I see nothing in the other answers regarding this I am creating a new one. In .Net 2, and earlier, you had to manually close the stream before closing the connection. That bug is fixed in all later versions of TcpClient in C# and as stated in the doc of the Close method a call to the method Close closes both the connection and the stream
EDIT according to Microsoft Docs
The Close method marks the instance as disposed and requests that the
associated Socket close the TCP connection. Based on the LingerState
property, the TCP connection may stay open for some time after the
Close method is called when data remains to be sent. There is no
notification provided when the underlying connection has completed
closing.
Calling this method will eventually result in the close of the associated Socket and will also close the associated NetworkStream that is used to send and receive data if one was created.
Use word: using. A good habit of programming.
using (TcpClient tcpClient = new TcpClient())
{
//operations
tcpClient.Close();
}
Despite having all the appropriate using statements, calling Close, having some exponential back off logic and recreating the TcpClient I've still been seeing issues where the application cannot recover the TCP connection without an application restart. It keeps failing with a
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
But there is an option LingerState on the TcpClient that appears it may have solved the issue (might not know for a few months as my own hardware setup only fails about that often!). See MSDN.
// This discards any pending data and Winsock resets the connection.
LingerOption lingerOption = new LingerOption(true, 0);
using (var tcpClient = new TcpClient
{SendTimeout = 2000, ReceiveTimeout = 2000, LingerState = lingerOption })
...
Except for some internal logging, Close == Dispose.
Dispose calls tcpClient.Client.Shutdown( SocketShutdown.Both ), but its eats any errors.
Maybe if you call it directly, you can get some useful exception information.
Closes a socket connection and allows for re-use of the socket:
tcpClient.Client.Disconnect(false);
The correct way to close the socket so you can re-open is:
tcpClient.Client.Disconnect(true);
The Boolean parameter indicates if you want to reuse the socket:
Have you tried calling TcpClient.Dispose() explicitly?
And are you sure that you have TcpClient.Close() and TcpClient.Dispose()-ed ALL connections?
client.Dispose();
client.Close();
if (stream != null)
{
clientstream.Dispose();
clientstream.Close();
}