Client/server: how to synchronize UDP send and receive in C? -
i writing simple web server , client using udp , far:
- the programs can connect each other,
- the client can send request,
- the server can read request,
- the server can recognize client's ip address , client's port, ,
- the server can send message client
my problem client code gets stuck waiting in rcvfrom
function, after server has sent response.
here function supposed pick server message , return number of bytes read socket:
ssize_t receive_from_server(rdp_socket *rsocket, char *buffer, size_t buf_len){ socklen_t sendsize = sizeof(rsocket->server_addr); bzero(&(rsocket->server_addr), sendsize); //stuck here: return recvfrom(rsocket->sockfd, buffer, buf_len, 0, (struct sockaddr*)&(rsocket->server_addr), &sendsize); }
i set sockopts both so_sndtimeo
, so_rcvtimeo
timeout after few seconds.
question:
in short term future adding acknowledgements (acks) reliable data transfer. imagine missing acks issue i'm wondering if, trained eye, looks different problem.
are acks necessary timeout work?
how can synchronize client , server can communicate each other?
since udp not provide reliability, need implement retransmission of missing data. since looks client request server response model, easiest retransmission implementation may resend request when time out waiting response, , wait response again. may want implement retry counter , give after number of retries.
if so_rcvtimeo
, so_sndtimeo
socket options not seem taking effect, may options not implemented type of socket. check return value of setsockopt()
call make sure succeeded.
as workaround, can change receive_from_server()
function use poll()
or select()
wait readable event amount of time, instead of blocking in recvfrom()
.
ssize_t receive_from_server(rdp_socket *rsocket, char *buffer, size_t buf_len){ struct pollfd pfd = { rsocket->sockfd, pollin }; int pollresult = poll(&pfd, 1, recv_timeout_seconds * 1000); if (pollresult > 0) { socklen_t sendsize = sizeof(rsocket->server_addr); bzero(&(rsocket->server_addr), sendsize); return recvfrom(rsocket->sockfd, buffer, buf_len, msg_dontwait, (struct sockaddr*)&(rsocket->server_addr), &sendsize); } if (pollresult == 0) { errno = etime; } return -1; }
Comments
Post a Comment