You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by ERIC WOOD <WO...@aaicorp.com> on 2009/04/01 21:23:22 UTC

Help with non-blocking UDP datagram receive

I am having trouble receiving UDP datagrams without blocking:  Here is
my code snippet:

  // Create the socket address
  rv = apr_sockaddr_info_get(&sa, "localhost", APR_INET, iPort, 0,
mp);
  if( rv != APR_SUCCESS )
  {
    std::cout << "Failed to get socket address for receiving messages"

		      << std::endl; 
	return -1;
  }
   
  // Create the socket
  rv = apr_socket_create(&s, sa->family, SOCK_DGRAM, APR_PROTO_UDP,
mp);
//  rv = apr_socket_create(&s, sa->family, SOCK_STREAM, APR_PROTO_TCP,
mp);
  if( rv != APR_SUCCESS )
  {
    std::cout << "Failed to create socket for receiving messages" <<
std::endl; 
	return -1;
  }

  // Set options
  apr_socket_opt_set( s, APR_SO_NONBLOCK, 1 );
  apr_socket_timeout_set( s, APR_USEC_PER_SEC );


  // Bind the socket.  
  rv = apr_socket_bind( s, sa );
  if( rv != APR_SUCCESS )
  {
    std::cout << "Failed to bind socket for receiving messages" <<
std::endl; 
	return -1;
  }

  finished = 0;

  char buf[1048];
  apr_size_t len = 1048;
  apr_sockaddr_t * saRecvdFrom;

  // Main loop
  std::cout << "\n\nUGCS Security Banner Client started. Enter CTRL+C
to \
exit.\n\n" << std::endl;
  while(!finished)
  {
    // Do blocking reads with 1 sec timeout to allow for signal
catching
    apr_status_t rv = apr_socket_recvfrom(sa, s, 0, buf, &len);
	if( rv != APR_SUCCESS && rv != APR_TIMEUP )
    {
	  char sError[1048];
	  apr_strerror( rv, sError, 1048 );
	  std::cout << "Error receiving data from socket.  Error: " 
		        << sError << "(" << rv << ")" << std::endl; 
	 // return -1;
    }
	
	if ( len > 0 )
	{
	  std::cout << "Data received" << std::endl;
	}
	std::cout << "tick" << std::endl;
	sleep( 1000 );
  }

 
This code on Windows causes a WSAEWOULDBLOCK error when no data is
received and a WSAEMSGSIZE when a datagram is received.  If I set it to
block and specify a timeout, then I get a WSAETIMEDOUT error when no
data is received and a WSAEMSGSIZE when a datagram is received.  If I
set it to block AND do not set a timeout, I receive the datagram
correctly, but then I can't do anything else while waiting for a
datagram (like catch the exit signal).  Any guidance you can provide is
appreciated.