How to set NoDelay socket option - supersocket.net

How to set NoDelay socket option (or socket options in general) with supersocket?

Ok that was easy, don't know why I didn't see it before.
Underlying Socket object is accessible through session.
WebSocketServer appServer;
appServer.NewSessionConnected += session =>
session.SocketSession.Client
.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.NoDelay, true);

Related

Qt unix domain socket server side reading

I am using Qt for unix domain socket and I have a question:
I want the server side read the message sent from the client side right after the connection established, below are my codes
if (!server->listen("mySocket2")) {
//lisetn for new connection
close();
return;
}
connect(server, &QLocalServer::newConnection, this, &MainWindow::readData);
And in the readData function
QLocalSocket *clientConnection = server->nextPendingConnection();
connect(clientConnection, &QLocalSocket::disconnected,
clientConnection, &QLocalSocket::deleteLater);
connect(clientConnection,&QLocalSocket::readyRead,
this,&MainWindow::readyReadData);
In the readyReadData function
QByteArray block;
block=clientConnection->readAll();
qDebug()<<block;
clientConnection->disconnectFromServer();
but the app always crashed, can you plz advise me on that?
I don't see any condition handling for when there are no pending connections. This case will cause nextPendingConnection() to return a nullptr (actually, just a zero), which may or may not cause the signal/slot connections to fail.

QTcpSocket KeepAliveOption on server side

I would like to set QTcpSocket::KeepAliveOption on the server side, so that the connection gets automatically disconnected when the network connection is lost for some time.
However, the documentation says:
On Windows Runtime, QAbstractSocket::KeepAliveOption must be set before the socket is connected.
On a client, you would just create the socket, set the option, then connect it.
On the server side, you do not create the sockets, they are created and returned buy QTcpServer::nextPendingConnection(). These are already connected.
So am I basically stuck, and is the only viable option to implement "heartbeats" myself?
EDIT
I have created a QTcpServer subclass as suggested by talamaki for setting the flag on incoming connection sockets:
class CustomTcpServer : public QTcpServer
{
Q_OBJECT
public:
CustomTcpServer(QObject * parent = 0) : QTcpServer(parent) { }
void incomingConnection(qintptr socketDescriptor)
{
QTcpSocket *socket = new QTcpSocket(this);
socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
socket->setSocketDescriptor(socketDescriptor);
addPendingConnection(socket);
}
};
Then, i have set
\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP\Parameters\KeepAliveTime
To a DWORD value of 30000 (thirty seconds)
And rebooted the system to be sure it is used by the system
But, I still get no disconnected signal after several minutes, after having unplugged the ethernet cable of the remote client.
How to make the KeepAlive feature work?
Thanks
You should be able override QTcpServer::incomingConnection and create QTcpSocket yourself instead of letting the framework do it.
On Windows, AFAIK there are three parameters that govern the timeout of a TCP connection. You have set the KeepAliveTime, which is the time until an idle connection will be starting to send keep-alive segments (the connection must be idle, no segments have been sent, no Acks received). Then there is the number of keep-alives that need to be unanswered to determine that it is dead, which is TcpMaxDataRetransmissions. Finally, the is the time between the keep-alive segments which is KeepAliveInterval. Check with Wireshark, if empty TCP segments are being sent (which are the Keep-Alives). Some versions of Windows might misbehave, too and ignore some of the settings.
Usually Servers re-starts the Listenning after a elapsed time without traffic. After close en re-open , new connections will arrive.
ALSO Client and Server can specify a test protocol like PING - PONG message on interval of X seconds, minutes, etc
In server side, when missing pings after X seconds, maybe indicate to restart the server.
Best regards!

DocumentDB: using TCP connection with client lib > 1.9.0

With Microsoft.Azure.DocumentDB 1.9.0 the ConnectionProtocol variable in the ConnectionPolicy has been made obsolete with the comment:
"This property is deprecated. Please use ConnectionMode to choose communication protocol in conjution with connection endpoint mode."
We still set it to Tcp, and we set ConnectionMode to Direct. However, when doing a Fiddler capture of our app I can see the requests going to DocumentDb over HTTPS.
How do I force the lib to use the Tcp connection? Do I have to change the endpoint string? Ours is currently of the form:
https://mydocumentdb.documents.azure.com:443
as that's what Azure tells us to use. I'm really not clear what the comment means by "connection endpoint mode".
EDIT: By request, here's my connection code:
DocumentDbConnection ConnectionData = new DocumentDbConnection();
ConnectionPolicy ClientConnectionPolicy = ConnectionPolicy.Default;
ClientConnectionPolicy.ConnectionMode = ConnectionMode.Direct;
ClientConnectionPolicy.ConnectionProtocol = Protocol.Tcp;
ConnectionData.DbClient = new DocumentClient( new Uri( DbEndpoint ), AccountKey, ClientConnectionPolicy );
// do initial connection upfront to avoid first-query latency
await ConnectionData.DbClient.OpenAsync();
DatabaseAccount DbAccount = await ConnectionData.DbClient.GetDatabaseAccountAsync();
Direct TCP mode is only supported for any requests for server resources(like Documents). Requests for master resources(like document collection) will still go through the Gateway.
Can you elaborate what kind of requests you are seeing in fiddler? Note that the client initialization related requests will also go through gateway and any subsequent requests for server resources will be directed using TCP.
Are you using partitioned collections feature?
Note that we brought back the ConnectionProtocol in .NET SDK 1.9.2(which was marked as Obsolete earlier). If you were setting the Protocol to TCP and Mode to Direct even earlier it should work as expected. No need to change the endpoint string.
Regards,
Rajesh

How to send RST manually with a custom server?

I am trying to debug a scenario, and for that I want the http server to close the connection via RST. Right now it is doing a graceful close with fin/ack.
Is there any way I can manually send a RST packet to close the connection as part of the current stream? may be a simple custom server?
thanks in advance for your help.
Assuming it is your own code, call setsockopt() with option=SO_LINGER and the linger structure set to l_onoff=1 and l_linger=0, and then close the socket. Any outbound data that is still buffered will be lost, which includes data already sent but not acknowledged.
Use this only for testing. It is insecure and unkind.
If it isn't your code in the server, write a client that does a GET of a large resource and closes the connection without reading any of the response.
Source: W.R. Stevens et al., Unix Network Programming, vol 1, 3rd edition, p.202.
For reference, code snippet for the setsockopt() with linger. Thanks to #EJB for the help.
With this option set, the server closes the connection with RST.
...
struct linger so_linger;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
...

How do I check client connection is still alive

I am working on a network programming using epoll. I have a connection list and put every client in the list. I can detect user disconnection by reading 0 if the user disconnected normally. However, if the user somehow got disconnected unexpectedly then there is no way it knows about this until it tries send data to the user.
I don't think epoll provides a nice way to handle this..so I think I should handle this on my own. I will be very appreciated if you guys can provide me anything like examples or references related to this problem.
epoll_wait will return a EPOLLHUP or EPOLLERR for the socket if the other side disconnects. EPOLLHUP and EPOLLERR are set automatically but you can also set the newer EPOLLRDHUP which explicitly reports peer shutdown.
Also if you use send with the flag MSG_NOSIGNAL it will set EPIPE on closed connections.
int resp = send ( sock, buf, buflen, MSG_NOSIGNAL );
if ( resp == -1 && errno == EPIPE ) { /* other side gone away */ }
Much nicer than getting a signal.
How about TCP Keepalives: http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html. See "Checking for dead peers". A later section on the same site has example code: http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/programming.html.

Resources