c - How to use sockets recv(,,,) for an indeterminate response length -
i have requirement send commands , read responses device using irda sockets communication. although packaging commands straight forward, determining expected size of response not possible. example command "get_errors" results in device returning data 0 n, \n
delimited lines of 80 bytes each. have read post *here, ***header preceding actual data block* not provided me device.
[edit]
here typical response get_errors command (shorted readability):
date time fault 10/12/2000 02:00:00 3f46 10/12/2000 02:00:00 bcf5 10/12/2000 02:00:00 1312 10/12/2000 02:00:00 a334 10/12/2000 02:00:00 b212 10/12/2000 02:00:00 b212 10/12/2000 02:00:00 c43a %
this example, (from post here) works if know length of data being returned:
int recv_all(int sockfd, void *buf, size_t len, int flags) { size_t toread = len; char *bufptr = (char*) buf; while (toread > 0) { ssize_t rsz = recv(sockfd, bufptr, toread, flags); if (rsz <= 0) return rsz; /* error or other end closed cnnection */ toread -= rsz; /* read less next time */ bufptr += rsz; /* next buffer position read */ } return len; }
but if want receive unknown amount of data, thing know declare large buffer, pass this:
int irdacommreceive(int irdacommsocket, void* largebuf, size_t len, int* rcvd) { char *bufptr = (char *)largebuf; int bytesrcvd = recv(irdacommsocket, bufptr, len, 0); if (bytesrcvd < 0) return wsagetlasterror(); *rcvd = bytesrcvd; return 0; }
is there better way write receive function sockets data of indeterminate size?
socket messages must framed in way guarantee integrity of communications. instance, udp datagram sockets send/receive self-contained messages, data cannot span across message boundaries. tcp stream sockets not have restriction, logical messages must delimited instead, either header describes message length, or unique terminator not appear in message data. irda sockets no different.
since have not shown actual data get_errors
response, or code matter, there no header in front of response message, leaves 2 possibilities:
message framing @ transport level. handled if creating irda socket using
sock_dgram
type. ifrecv()
using buffer small, message discarded ,wsaemsgsize
error.message delimiting @ application level. have handle if creating irda socket using
sock_stream
type. provide arbitrary buffer, ,recv()
fills whatever data available, requested size. callrecv()
again receive more data, continuing needed until find data looking for.
i assuming latter, since how irda typically used sockets. cannot find online documentation irda-based get_errors
command (do have such documentation?), have assume data has terminating delimiter not accounting for. may sending 0-n lines you, bet last line has length of 0, or equivalent. in case, call recv()
in loop until receive terminator.
Comments
Post a Comment