-->
Page 1 of 4

the reason of net.socket:send("payload") issue.

PostPosted: Thu Jan 08, 2015 12:44 am
by zeroday
In the firmware build after 20141219.
where SDK 0.9.4 and 0.9.5 are adopted.

multiple lines of
net.socket:send("hello\n")
net.socket:send("world\n")
net.socket:send("third line\n")

will NOT act as is.
probably only the first line ("hello") was sent.

the reason is due to the change in SDK file, lwip/app/espconn.c:
0.9.4 & 0.9.5: line 275.
Code: Select all        case ESPCONN_TCP:
            if (value && (pnode->pcommon.write_len == pnode->pcommon.write_total)){    // this line cause the issue
                 espconn_tcp_sent(pnode, psent, length);
            }else
               return ESPCONN_ARG;
            break;

        case ESPCONN_UDP: {
           if (value)
              espconn_udp_sent(pnode, psent, length);
           else
              return ESPCONN_ARG;
            break;
        }


0.9.2: line 252
Code: Select all        case ESPCONN_TCP:
            if (value)                                                              // diff here
               espconn_tcp_sent(pnode, psent, length);
            else
               return ESPCONN_ARG;
            break;

        case ESPCONN_UDP: {
           if (value)
              espconn_udp_sent(pnode, psent, length);
           else
              return ESPCONN_ARG;
            break;
        }


this code means, only when the previous send() is done(inside sent callback is triggered).
the next send will take effect. otherwise, espconn_tcp_sent will not called.

so, the solution maybe:
1, roll back to 0.9.2, if data send with big chunk is called too fast. some data lost(overwritten).
2, call send when the previous send is done.
3, use a block send(), return when previous send is done. (may cause watchdog issue, if data is huge.)

any ideas?

Re: the reason of net.socket:send("payload") issue.

PostPosted: Thu Jan 08, 2015 1:20 am
by yes8s
Ah, ok - Thanks for getting to the bottom of this. At least we now understand and can explain what's happening.

I think we know the tcp buffer is around 1400 or so bytes long so we don't want to exceed that when calling the tcp routine.

1. I don't think we should revert back to 0.9.2. It doesn't make sense since we will not be tracking espressif development anymore and benefiting from other improvements.

2. This is feasible and is what I'm currently doing. i.e. Next send("xxx") is triggered within the on('sent'..) callback until all data is sent at which point I close connection and exit. Problem with this is that it is too slow. It may be possible to get speed back by somehow concatenating data to be sent, kind of like filling a large buffer but I'm not sure how this can be done effectively without wasting up heap.

3. A block send may be possible but I'm not sure how this would work without using memory or holding up the program.

Is there anyway of progressively filling the underlying C TCP buffer (so as to utilize existing resources) and then trigger a send data command when either the buffer has filled or application tells it to send. Either way nodeMCU or the application may have to keep track of the number of bytes and keep track of what it is sending and when it is finished reading in data to be sent.

A tricky problem to solve...

Re: the reason of net.socket:send("payload") issue.

PostPosted: Thu Jan 08, 2015 3:04 am
by picstart
multiple lines of
net.socket:send("hello\n")
net.socket:send("world\n")
net.socket:send("third line\n")

will NOT act as is.
probably only the first line ("hello") was sent.

Really!
So after 0.92 above result represents an advanced feature of the SDK duh!

Frankly, I don't see esp8266 beyond 0.9.2. as viable except for very very small data transfers.
Anyway esp8266 has been a nice toy but has very very limited TCP utility unless you can keep all data transfers to less than a few hundred bytes.
Sure there are clumsy work a rounds but the writing is on the wall that future SDK development is going no where.

Other chips like TI are more expensive but at least they are more than toys.

0.9.2. SDK was the zenith of esp8266 it is very sad to see esp8266 have such a limited lifespan.
I fell bad for those like zeroday and Nodemcu plus all the others hoping to make the esp8266 viable only to see recent SDK releases leave them with severely restricted capabilities.

Lets hope the death of the esp8266 is premature and that a future SDK may recover the value of the earlier 0.9.2 SDK nevertheless any confidence in the SDK developers is lost.
Maybe zeroday can keep developing Nodemcu based on 0.9.2 exclusively and reject all future SDK's until the few hundred byte transfer limitation is addressed.

Re: the reason of net.socket:send("payload") issue.

PostPosted: Thu Jan 08, 2015 3:21 am
by zeroday
I have just pushed a build 20150108.
to solve this problem partially.

so, here is the thing.
multi line sends will be return immediately, and the payload is put into TCP buffer. like the SDK 0.9.2 does.
this is good for sending many little data. say 10+ lines send() send a total <1460 bytes.

"sent" callback will be called once when:
the last chunk into the TCP buffer is send, and the next packet is not put into buffer already.

multi-lines of sends, send more data than the TCP buffer(maybe 2920 bytes), will cause a data lose.
in this situation. call send() AFTER the previous send() triggered a "sent" callback.