Thread: socket recv() doesnt receive data

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    7

    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).

  2. #2
    Registered User
    Join Date
    Apr 2012
    Posts
    7
    EDIT: I have figured that when the daemon sends the data, the select() on the client side returns that the socket is readable, but recv() is blocking, thats the reason I'm not getting data on the client side. Any suggestions on how to fix this?



  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    select will change your fd_sets, so read_fds may not be what you think at the top of your loop. Read this section from Beej's guide: Beej's Guide to Network Programming. Pay close attention to his use of the "master" fd_set.

    Other than that, I can't say too much without seeing how you establish and set up your connections, fd_sets, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 04-09-2012, 07:12 AM
  2. Use one socket to send and receive message (using UDP)
    By tanya9x in forum C++ Programming
    Replies: 11
    Last Post: 02-28-2010, 05:58 AM
  3. Receive a TCP message on a UDP socket?
    By Yarin in forum C++ Programming
    Replies: 5
    Last Post: 09-05-2009, 12:21 AM
  4. How to make a nonblocking receive socket?
    By Aidman in forum Windows Programming
    Replies: 3
    Last Post: 04-30-2003, 04:28 PM

Tags for this Thread