This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

TCP-server cannot accept clients

Hi!

I'm developing a TCP server running on the nRF9160, but there seem to be a problem with accepting clients. The code is very simple, just calls to socket, bind, listen, accept. But the accept fails as soon as a client tries to connect. ERROR on accept returned -1, errno: 134. I have pasted the code below.

I'm connected to a Cat-M network before I start the server and I have successfully connected from the nRF9160 to another server. But I cannot get the nRF9160 to act as a server. Can you please investigate this?

I'm using:
fw-nrfconnect-nrf tag v1.1.0
Zephyr tag v2.0.99-ncs1
nrfxlib v1.1.0
Modem firmware: 1.1.0

int parentfd; /* parent socket */
int childfd; /* child socket */
int portno; /* port to listen on */
int clientlen; /* byte size of client's address */
struct sockaddr_in serveraddr; /* server's addr */
struct sockaddr_in clientaddr; /* client addr */

portno = 8080;
parentfd = socket(AF_INET, SOCK_STREAM, 0);
if (parentfd < 0) {
	LOG_ERR("ERROR opening socket");
	return;
}

memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = INADDR_ANY;
serveraddr.sin_port = htons((unsigned short)portno);

if (bind(parentfd, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) {
	LOG_ERR("ERROR on binding");
	return;
}

if (listen(parentfd, 5) < 0) {/* allow 5 requests to queue up */ 
	LOG_ERR("ERROR on listen");
	return;
}

while (1) {
	LOG_INF("TCP server waiting for client...");

	childfd = accept(parentfd, (struct sockaddr *) &clientaddr, &clientlen);
	if (childfd < 0) {
		LOG_ERR("ERROR on accept returned %d, errno: %d", childfd, errno);
		LOG_ERR("Closing server");
		close(parentfd);
		break;
	}

	LOG_INF("server established connection");
	
	tcp_handle_client(childfd);

	close(childfd);
} 

Kind regards

Mattias Eriksson

Parents
  • Hi.

    First of all, I need a bit more information to make sense of the error you get, 134.

    NCS can be built with two different libc implementations, newlib and Zephyr's own minimal implementation. Which one of those are you using (, i.e. have you enabled the newlib implementation)?

    If you are using newlib, you can get an explanation of the error by calling strerror(). It is declared in string.h, and returns a string that explains the error.

    Best regards,

    Didrik

  • Thanks for fast response!

    Yes, I'm using newlib (CONFIG_NEWLIB_LIBC=y).

    This is the error string I get from strerror(134): 'Not supported'.

    You can see the error code for newlib here also (for example): Newlib errno.h

    That is not good.. According to your nrfxlib/bsdlib documentation you support both TCP client and server (http://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrfxlib/bsdlib/README.html)

    Note that the error is returned when a client connects, not when the function is called.

    Kind regards

  • May I ask why you want to run a TCP server on the nRF91?

    Looking at the IP traffic in your trace, I only find a single TCP handshake. Also, from the modem side, it looks like the accept() call succeeds, and new socket is created. So it does not look like the problem is in the modem. I have heard that the TCP server support in bsdlib is not very strong, because of the limited use server functionality would have on a low power cellular device.

  • We are migrating from our current solution (using 2g/3g/4g) where our cloud/server connects to devices and pushes data once in a while. This infrastructure is not something we can change in a heartbeat.

    We also want to be able to connect a telnet shell to the devices every once in a while for development, debugging and configuration.

    It sounds promising that it all looks good from the modems point of view.

    It does not sound good that the server support in bsdlib "is not very strong". I think it is odd that you would not support it, why would server be so much more strange or difficult than client? Is it something you will fix or will you stop supporting it?

    Best regards

  • I have asked the bsdlib team for clarification and will get back to you when I get an answer.

    The reason for why the server functionality is not as tested as the client functionality is that in most use cases, the nRF91 will be the client, and the one to initiate the contact. This is both due to power management concerns, but also due to the way the LTE network is implemented. From a power management perspective, it is not optimal to be connected to the network at all times and listen for incoming connections. And from the network side, the device is often heavily sandboxed behind NAT and firewalls, controlled by the network operators. All this means that the server functionality is not much used, and therefore not given as much attention as the client functionality.

    That said, as we do list it as a supported feature, and provide the necessary APIs to use it, it should definitely work. If it is a bug that is causing your problems, I expect that it will be fixed, and I do not expect that we will drop support for TCP server functionality. But, when it comes to support of features etc. your Regional Sales Manager would be more appropriate than a DevZone case. Anyway, as I said, I have asked the bsdlib team to look into your problems, and will get back to you when I get a reply from them.

  • Thank you.

    I understand that this is not the most common use case. NAT is not a problem for us since our devices are not public on the internet, we have VPN to our network providers.

    We look forward hearing what the bsdlib team says.

    Best regards

Reply Children
  • Hi, and sorry for the long wait.

    It took some time to find someone at the bsdlib team that could answer, and he needs to check with the modem team, so it will take a bit longer to get a definitive answer.

    The answer I have gotten so far is that the nRF9160 should support server functionality in theory, but it has not been much tested and there could also be some issues on the network side.

    Thank you for your patience, and best regards,

    Didrik

  • Hi.

    We have found a bug in the translation layer between Zephyr and bsdlib which might be the cause of the error you are seeing.

    There is a pull request open with a fix. Could you try to apply that fix to your project, and see if that solves your problem?

    You can find the PR here: https://github.com/NordicPlayground/fw-nrfconnect-nrf/pull/1885

    Best regards,

    Didrik

  • Hi

    Yes, this appears to solve the issue!

    However, the TCP connection does not seem to work as I expect.
    Recv does not return even when the other end closes the connection (gracefully). I think it should?


    To deal with this I added a read timeout and close the TCP connection myself (from nRF91) when I don't receive any more data. After this I would like to start listen for a new incoming connection. So I call accept again. Just like the example I provided in my question above.

    However, 'accept' returns 119: EINPROGRESS 119 /* Connection already in progress */

    Even if I wait and retry. It will return this forever. I think this is not as it is supposed to be?

    Best regards

  • MattiasE said:
    Yes, this appears to solve the issue!

     Great to hear.

     

    MattiasE said:
    However, the TCP connection does not seem to work as I expect.
    Recv does not return even when the other end closes the connection (gracefully).

     That's not so great to hear. I have forwarded it to the bsdlib team. Again, could you take a modem trace?

  • I have captured two events now. In both traces I send "Hello Nordic!" at the start of the TCP connection.

    In the first one I have set the receive timeout to 5 seconds. After this I close the socket and try to accept new connections, which fails:

    [00:00:21.374,481] <inf> tcp_srv: TCP server waiting for client...
    [00:00:23.640,502] <inf> tcp_srv: server established connection with x.x.x.x
    [00:00:23.640,533] <err> tcp_srv: Handling TCP client..
    [00:00:25.351,898] <inf> tcp_srv: Bytes received: 14
    [00:00:30.352,020] <err> tcp_srv: recv failed with error: -1
    [00:00:30.363,952] <inf> tcp_srv: TCP server waiting for client...
    [00:00:30.564,636] <err> tcp_srv: ERROR on accept returned -1, errno: 119
    [00:00:30.564,636] <err> tcp_srv: ERROR 'Connection already in progress'
    [00:00:30.564,636] <err> tcp_srv: Closing server

    The log does not say it, but there is a call to 'close' of the client socket right after the 'recv' fail.

    trace-2020-02-14T10-02-38.495Z recv timeout, accept fail.bin

    In the second trace I just try to receive all data, but 'recv' does not return when I shut down the connection from the other end:

    00:00:26.577,392] <inf> tcp_srv: server established connection with x.x.x.x
    [00:00:26.577,423] <err> tcp_srv: Handling TCP client..
    [00:00:29.082,824] <inf> tcp_srv: Bytes received: 14
    ...Nothing more...

    trace-2020-02-14T10-04-53.383Z recv no return.bin

    I hope this will help you debug it.

    I'm still using:
    fw-nrfconnect-nrf tag v1.1.0 (+ the fix you provided above)
    Zephyr tag v2.0.99-ncs1
    nrfxlib v1.1.0
    Modem firmware: 1.1.0

Related