[PD-dev] socket gurus

august august at alien.mur.at
Wed Mar 3 21:09:35 CET 2004


ok, finally got it.

let me know if this looks ok.

you first use fcntl to set the socket to non-blocking mode.

then you connect , expecting errno to be EINPROGRESS,  ...then selecting
on the socket with a timeout value to see if it is ready.
 

Olaf, this should fix the same problem with oggamp~ and mp3amp~.....and I
noticed that x_net.c from pd/src is affected by this problem

netsend will hang and block pd entirely on a netsend connect to certain
ip's and ports.

this should also "fix" that as well, assuming pd is willing to wait for a
timeval while connecting with netsend.  the comments in .37 version
suggest that this will  be put into a thread.


thanks for the help  -august.

 
----------------------------------------


  int flags = fcntl( fd, F_GETFL, 0);
  fcntl( fd, F_SETFL, FNDELAY);     // make this socket's calls non-blocking 
  //  fcntl( fd, F_SETFL, flags | O_NONBLOCK);

  if (connect( fd, (struct sockaddr *) &server, sizeof(server) ) == -1 && errno != EINPROGRESS) { 
    /*
     * If non-blocking connect() couldn't finish, it returns
     * EINPROGRESS.  That's OK, we'll take care of it a little
     * later, in the select().  But if some other error code was
     * returned there's a real problem...
     */
    sys_closesocket (fd);
    return(-1);
  
  } else {

    FD_ZERO (&fdset);
    FD_SET (fd, &fdset);
    tv.tv_sec = 1;              /* seconds */
    tv.tv_usec = 0;     /* microseconds */

    // you want to do the select on the WRITEablity of the socket, 
    // HTTP expects a get command, so make sure to pass args to 
    // both read and write fdset
    switch (select( fd+1 , &fdset, &fdset, NULL, &tv) ) {
      /*
       * select() will return when the socket is ready for action,
       * or when there is an error, or the when timeout specified
       * using tval is exceeded without anything becoming ready.
       */
      
    case 0:     // timeout 
      //do whatever you do when you couldn't connect
      cout << "InputStream:: connect timed out" <<endl;
      sys_closesocket (fd);
      return (-1);
      break;
    case -1:    // error 
      cout << "InputStream:: connection error" <<endl;
      sys_closesocket (fd);
      return (-1);
      break;
    default:    // your file descriptor is ready... 
      fcntl( fd, F_SETFL, flags);       
      break;
    }
  }





More information about the Pd-dev mailing list