socket recv() doesnt receive data
I have a server daemon listening on a TCP unix domain/local socket. Multiple clients running on the same machine connect to it. The daemon is also bound to a UDP Internet socket. Whenever the daemon receives any data from one of the local clients, it sends the same data to all the connected clients except the sending client. If the daemon receives data on the udp internet socket, it needs to send that data to all the local connected clients. The sending/receiving of data works perfectly when the daemon receives data on the local socket. However, the clients do not receive any data when the server sends them data received on the udp internet socket. The clients receive that internet data either after the server daemon is exited and the connection is closed, or, when any of the clients sends data locally to the server.. the internet data is received by the clients along with the local data. I have set both local and inet sockets as blocking using fcntl. Here is the daemon code that I have (I have removed all the unncessary code):
Code:
while(1)
{
FD_SET(sockfd, &read_fds);
FD_SET(inet_sock, &read_fds);
for (i = 0; i < nclients; i++)
{
FD_SET(clients[i], &read_fds);
}
select(maxfd + 1, &read_fds, &write_fds, &except_fds, NULL);
/* Check for events on inet sock */
if (FD_ISSET(inet_sock, &read_fds))
{
/* Read from inet sock */
socklen = sizeof(dest_sin);
rval=recvfrom(inet_sock, buf, BUFLEN-1, MSG_DONTWAIT, (struct sockaddr *) &dest_sin, &socklen);
buf[rval]=0;
fprintf(stderr, "Received: %d (%d) bytes containing %s", rval, strlen(buf), buf);
/* Send the message to every other client */
for(j=0; j < nclients; j++)
{
send(clients[j], buf, strlen(buf), MSG_DONTWAIT);
}
}
/* A read event on the local socket is a new connection */
if (FD_ISSET(sockfd, &read_fds))
{
socklen = sizeof(dest_sun);
/* Accept the new connection */
rval = accept(sockfd, (struct sockaddr *) &dest_sun, &socklen);
/* Add client to list of clients */
clients[nclients++] = rval;
if (rval > maxfd) maxfd = rval;
snprintf(s, BUFLEN, "You are client %d [%d]. You are now connected.\n\0",
nclients, rval);
send(rval, s, strnlen(s, BUFLEN), MSG_DONTWAIT);
}
/* Check for events from each client */
for (i = 0; i < nclients; i++)
{
fprintf(stderr,"Checking client %d [%d] for read indicator.\n",i, clients[i]);
/* Client read events */
if (FD_ISSET(clients[i], &read_fds))
{
fprintf(stderr, "Client %d [%d] marked for read.\n", i, clients[i]);
/* Read from client */
rval=recv(clients[i], buf, BUFLEN-1, MSG_DONTWAIT);
buf[rval]=0;
fprintf(stderr, "Received: %d (%d) bytes containing %s", rval, strlen(buf), buf);
/* Send the message to every other client */
for(j=0; j < nclients; j++)
{
/* Skip the sender */
if (j == i) continue;
/* Send the message */
send(clients[j], s, strlen(s, BUFLEN), MSG_DONTWAIT);
}
}
}
}
Here is the client code that I have:
Code:
while(1)
{
FD_SET(fileno(stdin), &read_fds);
FD_SET(sockfd, &read_fds);
select(fileno(stdin) > sockfd ? fileno(stdin)+1 : sockfd+1,
&read_fds, &write_fds, &except_fds, NULL);
if (FD_ISSET(sockfd, &read_fds))
{
/* Read from socket and display to user */
mlen = recv(sockfd, (void *)buf, BUFLEN-1, MSG_DONTWAIT);
buf[mlen]=0;
printf("Received %d bytes: %s", mlen, buf);
}
if (FD_ISSET(fileno(stdin), &read_fds))
{
fgets(buf, BUFLEN, stdin);
fprintf(stderr, "Sent %d octets to server.",
send(sockfd, (void *)buf, (size_t) strnlen(buf, BUFLEN), 0));
}
}
The goal is to have the clients receive data immediately that the daemon sends them ( the data which the daemon receives on its inet socket).