Socket accepting method id like while true - c#

TcpListener tcpserver;
Socket serverSocket = tcpserver.AcceptSocket();
Here 2nd line is like while(true) I mean till it any client gets connected to tcp server
it will not execute any line below it.
What my problem is: I want to accept multiple clients through this tcpserver but based on a flag like if admin_flag is TRUE then accept connection otherwise not. And this flag is going to toggle at any time by different thread.
I write this code:
while (true)
{
if(admin_flag==true)
{
Socket serverSocket = tcpserver.AcceptSocket();
}
else
// do something...
}
when I run it once, client is get connected. but when admin_flag is toggled i.e set to false it is not going in else part this is because the control remains in Accepting state
of socket & not executing other part even if it it while(TRUE).
plz guide??

AcceptSocket is a blocking method call which means that it will block the thread of execution until it can accept an incoming connection. If no connection is established with your listener then the call will continue to block indefinitely.
You would have to for example either stop the listener or switch to accepting connections asynchronously using the non-blocking BeginAcceptSocket or AcceptSocketAsync methods.

Related

Socket.Disconnect vs Socket.Close

What is the difference and which rules I must follow when working with socks?
I'm writing simple daemon, which must listen port and do some actions.
Socket.Close calls Dispose (but it's undocumented).
When using a connection-oriented Socket, always call the Shutdown method before closing the Socket. This ensures that all data is sent and received on the connected socket before it is closed. (msdn)
Your code should looks like this (at least I'd do it like this):
using (var socket = new Socket())
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
The Disconnect method takes a single parameter bool reuseSocket , according to msdn:
reuseSocket
Type: System.Boolean
true if this socket can be reused after the current connection is closed; otherwise, false.
which basically means, when you set reuseSocket to false it will be disposed after you close it.
The Shutdown method will not disconnect your socket, it will just disable sending/receiving data.

C# Sockets: accept a socket, ignore its message, send one back

We have a C# server that receives TCP messages using sockets. The normal flow is to call socket.Accept(), use socket.BeginReceive() and socket.EndReceive() to receive the message, then use socket.Send() to send a response. This works fine.
When too many requests come in at once, however, we want to reject the overflow immediately, so we don't overwhelm the server. It's easy enough to close the socket directly after Accept(); but that doesn't allow us to send a meaningful "too busy" message back to the client.
What I'd like to do is simply call Accept(), then call Send(), without receiving the incoming message. I have tried this, and the server claims to send my data, but my client receives nothing but an empty response. I have tried using both the synchronous Send() and the asynchronous BeginSend()/EndSend(), but neither gets the message back to the client.
Is it possible to send a message on an accepted socket without first receiving the incoming message? If so, is there a piece I'm missing to make it work?
Here's a code snippet showing what I'm trying to do:
while (!_Done)
{
Socket socket = null;
try
{
socket = _ListeningSocket.Accept();
}
catch (Exception) { }
if (socket != null)
{
if (TooBusy())
{
// My new code
byte[] send = GetTooBusyResponse();
int ret = socket.Send(send);
Console.WriteLine("socket.Send() returned " + ret);
socket.Close();
socket = null;
}
else
{
// Existing, working code (using custom objects)
ClientConnection connection = new ClientConnection(this, socket, !_RequireAuthentication);
lock (_ConnectionsToken)
_Connections.Add(connection);
connection.BeginReceive();
}
}
}
According to MSDN,
The Close method closes the remote host connection and releases all
managed and unmanaged resources associated with the Socket. Upon
closing, the Connected property is set to false.
For connection-oriented protocols, it is recommended that you call
Shutdown before calling the Close method. This ensures that all data
is sent and received on the connected socket before it is closed.
If you need to call Close without first calling Shutdown, you can
ensure that data queued for outgoing transmission will be sent by
setting the DontLinger Socket option to false and specifying a
non-zero time-out interval. Close will then block until this data is
sent or until the specified time-out expires. If you set DontLinger to
false and specify a zero time-out interval, Close releases the
connection and automatically discards outgoing queued data.
So either call Shutdown first, or set the DontLinger option to false and set a non-zero timeout.

Periodically send data from server to clients

I have created an asynchronous server that can read in messages from any number of clients. My server code is closely related to this example: http://msdn.microsoft.com/en-us/library/fx6588te.aspx
After a client connects I would like to periodically send out data to that client, maybe 2 or 3 times per second. I can't think of a good way to achieve this with an asynchronous send(). I'm assuming that some sort of timing mechanism would need to be added to my AcceptCallback() method because that is where the connection to the client happens.
In the previous version of my server I used blocking sockets and just looped my send() method in an infinite while() loop and called sleep() to get the timing down.
Here's what I'm thinking:
public void AcceptCallback(IAsyncResult ar)
{
allDone.Set(); // Signal the main thread to continue.
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
IPEndPoint remotePoint = (IPEndPoint)handler.RemoteEndPoint;
IPAddress remoteAddress = remotePoint.Address;
Console.WriteLine("Connected to {0}!", remoteAddress.ToString());
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
//Start periodically sending here??
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
I would set up a Timer object to send data to the client. Instantiate and start the timer in the AcceptCallback method at your comment. You'll have to keep track of information to allow that timer callback to send data to the client (like the socket, and some sort of test to allow it to stop--although you can simply turn the timer off, but you'd have to keep track of the timer in that case).
BTW, never call Sleep in situations like this because that commits your thread to sitting around for some period of time and you can't easily abort it to get the thread back (to exit or use for something else).

Thread and TcpListener in C#

I need to write some code that uses TcpListener. The object that using the TcpListener has 3 possibilities: Listen, Stop Listen, Send message. This is how my code looks:
public class someClass
{
public bool listenerEnable {get; set; }
public void StartListen()
{
.
.
.
while (listenerEnable)
{
// Block until client connected
TcpClient client = server.AcceptTcpClient();
// code that doing something with the client message ...
}
}
}
Now, I'm not sure I know how I can keep the thread safe when I want to stop the listener state (change the listenerEnable to be false).
Also I'm not sure I know how to keep this thread safe when I want to send some message to the client (in some separated method) without stopping the server listener state.
Thanks for any help.
I would suggest waiting on an event rather than waiting on a variable. In your current scheme, consider the case when your loop test for whether listener variable is true. If it is it enters the loop and waits for a incoming connection, and blocks. So now even if another thread sets the listener variable to be false, your loop will not exit till someone connects to it and it processes that connection.
One way of working around the problem above will be to have code like:
WaitHandle[] waitHandles = new WaitHandle[] {endlLoopEvent};
while(true)
{
int ret = WaitHandle.WaitAny(waitHandles, 100);
if(WaitTimeout == ret) continue;
else if(0 == ret) break; //our event has been signaled.
else
{
if(!server.Pending()) continue; //Go back to the loop if no connection pending
TcpClient client = server.AcceptTcpClient();
// You can spawn a thread to service the request.
}
}
Sending would not affect the loop above, provided it is not in response to a request for connection above.
Writing a correct, scalable socket server is not simple - I suggest you find / buy one - this has been done many times before.
To answer your question, your problem is that AcceptTcpClient is a blocking call. You will want to use the APM ( Asyncronous Programming Model ) methods that start with BeginXXX and EndXXXlike MSDN BeginAcceptTcpClient.
These methods don't block threads, but you will have to handle the concurrency.

Proper way to stop listening on a Socket

I have a server that listens for a connection on a socket:
public class Server
{
private Socket _serverSocket;
public Server()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, 1234));
_serverSocket.Listen(1);
}
public void Start()
{
_serverSocket.BeginAccept(HandleAsyncConnectionMethod, null);
}
public void Stop()
{
//????? MAGIC ?????
}
//... rest of code here
}
What is the correct (clean) way to close down the socket?
Is it sufficient to call:
_serverSocket.Disconnect(true);
in the Stop() method? or is there other work that needs to happen to close the connection cleanly?
TCP connection termination correctly involves a four-way handshake. You want both ends to inform the other that they're shutting down and then acknowledge each other's shutdown.
Wikipedia explains the process: http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination
This post explains how to make it happen in C#: http://vadmyst.blogspot.com/2008/04/proper-way-to-close-tcp-socket.html
2 ways to close it properly without exceptions
1) create temporary connecting socket and connect it to listening one so it could have its handler triggered then just finish it with normal EndAccept and after that close both.
2) just Close(0) listening socket which will result in false shot to its callback, if you then look into your listening socket you will see that its state is "closed" and "disposed". This is why calling EndAccept would cause exception. You may just ignore it and do not call EndAccept. Listening socket will go down immediately without timeout.
Since you are listening for incoming TCP connections, you could use System.Net.Sockets.TcpListener which does have a Stop() method. It does not have asynchronous operations though.
The cleanest way to have Accept call break immediately is to call _serverSocket.Dispose();
Any other call to methods in the like of Shutdown or Disconnect will throw an exception.
First, you need to make sure you're keeping track of any client sockets that were created in the process of BeginAccept. Shut those down first using the Socket.Shutdown() and Socket.Close() methods. Once those have all been shut down then do the same on the listening socket itself.
That should handle it...but if you need to make absolutely sure, you could always kill it with fire:
Not for sockets, but same idea applies., which is to close it in every way possible, then finally set the socket to null.
You should use Socket.Shutdown() and then Socket.Close(). Socket.Disconnect() is usually only used if you intend on reconnecting the same socket.

Categories