Nikhil
Nikhil

Reputation: 2318

Sending/Handling partial data writes in TCP

So, I have the following code which sends out my packet on TCP. Its working pretty well. I just have to test partial writes. So I write 1 byte at time either by setting sendbuf to 1 or do a hack as shown below. When i took a tcpdump, it was all incorrect except the first byte.. what am i doing wrong?

int tmi_transmit_packet(struct tmi_msg_pdu *tmi_pkt, int len, int *written_len)
{
int bytes;

// This works
bytes = write(g_tmi_mgr->tmi_conn_fd, (void*) tmi_pkt, len); 

// This doesn't: 
// bytes = write(g_tmi_mgr->tmi_conn_fd, (void*) tmi_pkt, 1); 

if (bytes < 0) {
    if (errno == EAGAIN) {
        return (TMI_SOCK_FULL);
    }
    return (TMI_WRITE_FAILED);
} else if (bytes < len) {
    *written_len += bytes;
    tmi_pkt += bytes;
    return (tmi_transmit_packet(tmi_pkt, len - bytes, written_len));
} else {
    *written_len += len;
}
return TMI_SUCCESS;
}

Upvotes: 0

Views: 505

Answers (1)

alk
alk

Reputation: 70931

This line

tmi_pkt += bytes;

most propably does not do what you expect.

It does increment tmi_pkt by sizeof(*tmp_pkt) * bytes and not only by bytes. For a nice explanation on pointer arithmetics you might like to click here and have a look at binky.

To get around this you might mod you code as follows:

...
else if (bytes < len) {
  void * pv = ((char *) tmp_pkt) + bytes;
  *written_len += bytes;
  return (tmi_transmit_packet(pv, len - bytes, written_len));
}
...

Anyhow this somehow smells dirty as the data pointed to by the pointer passed into the write function does not necessarly need to correspond to it's type.

So a cleaner solution would be to not used struct tmi_msg_pdu *tmi_pkt but void * or char * as the function parameter declaration.

Although quiet extravagant the use of recursive calls here is not necessary nor recommended. For much data and/or a slow transmission it may run out of stack memory. A simple loop would do also. The latter has the advantage that you could use a temporary pointer to the buffer to be written and could stick to a typed interface.

Upvotes: 2

Related Questions