'App stucks in accept() when LAN interfaces changed
I created a small app on small router with 4 LAN ports. Router has been flashed with OpenWrt system, Linux kernel 5.4.154 Devices connected to LAN ports are sending date over TCP POSTs. The app is listening on specified TCP port and sends data to the server or stores it in SD card. Everything work fine until someone will start playing with plugs on the LAN side. Somethings is happening and app hangs in accept() function waiting for incomming data.
I assume (please correct me if I'm wrong) system changes?/resets? port routing and data are not delivered to the app socket any more.
Is there a simple solution to keep the 'subscription' of TCP port? I've tried to rewrite app in async mode, but not everything is working correctly, is this the only solution for this problem?
Below simpyfied working(!) code in blocking mode (I removed all unnecesary stuff, so it may not compile)
int main() {
// Create server_socket as socket
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
cerr << "Can't create a socket! Quitting" << endl;
}
int enable = 1;
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
{
cout << GetTime() << "Can't use SO_REUSEADDR" << endl;
}
while (true) {
// Bind the ip address and port to a socket
listenningport = 55555;
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(listenningport);
inet_pton(AF_INET, "0.0.0.0", &hint.sin_addr);
if (bind(server_socket, (sockaddr*) &hint, sizeof(hint)) == -1) {
cerr << "Can't bind to IP/port" << endl;
}
// Tell Winsock the socket is for server_socket
if (listen(server_socket, SOMAXCONN) == -1) // handle multiconnections SOMAXCONN(4096, queue)
{
cerr << "Can't listen!" << endl;
}
// Wait for a connection
sockaddr_in client;
socklen_t clientSize = sizeof(client);
while (true) {
// Waiting for data on socket; block mode
int clientSocket = accept(server_socket, (sockaddr*) &client, &clientSize);
if (clientSocket == -1) {
cerr << "Problem with client connecting!" << endl;
// break the loop and try to renew socket connection
break;
}
else {
// receive all data till the end of message
int bytesReceived = 0;
while ((bytesReceived = recv(readSocket, out_data + msgSize, maxSizeOutData - msgSize - 1, 0)) > 0) {
msgSize += bytesReceived;
if (msgSize > maxSizeOutData + 1)
break;
}
// no data received
if (bytesReceived == -1) {
cerr << "Error in recv(). BytesReceived = -1" << endl;
}
close(clientSocket);
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
