If a connection sends data in one way, then the receiver will have shut
down data in the other way, and when the sender is finished he will also
shut down his direction, so the connection looks closed to the sender,
but the receiver might actually still miss the final packets. So UTCP
should keep running until the receiver has received a FINACK and is in the
TIME_WAIT state.
We consider UTCP to be active when there is at least one connection not in
the CLOSED or TIME_WAIT state.
The test program now uses this condition, which allows a transfer of a file
to complete without missing the last few bytes.
char buf[102400];
struct timeval timeout = utcp_timeout(u);
- while(dir) {
+ while(!connected || utcp_is_active(u)) {
size_t max = c ? utcp_get_sndbuf_free(c) : 0;
if(max > sizeof buf)
max = sizeof buf;
return diff;
}
+bool utcp_is_active(struct utcp *utcp) {
+ if(!utcp)
+ return false;
+
+ for(int i = 0; i < utcp->nconnections; i++)
+ if(utcp->connections[i]->state != CLOSED && utcp->connections[i]->state != TIME_WAIT)
+ return true;
+
+ return false;
+}
+
struct utcp *utcp_init(utcp_accept_t accept, utcp_pre_accept_t pre_accept, utcp_send_t send, void *priv) {
struct utcp *utcp = calloc(1, sizeof *utcp);
if(!utcp)
extern void utcp_set_recv_cb(struct utcp_connection *connection, utcp_recv_t recv);
extern void utcp_set_poll_cb(struct utcp_connection *connection, utcp_poll_t poll);
extern void utcp_set_accept_cb(struct utcp *utcp, utcp_accept_t accept, utcp_pre_accept_t pre_accept);
+extern bool utcp_is_active(struct utcp *utcp);
// Global socket options