views:

23

answers:

0

Hi,

I'm trying to write a client. I am able to open a socket to the server and the server acknowledges the connection, but for some reason, the write stream is never ready to accept data, i.e. it seems to always be blocked. What am I doing wrong? I'm new to socket programming, so it might be something in the wrong place, but here's what I have (I got most of it from sample code):

int main(int argc, char **argv) {

  CFSocketRef TCPClient;
  CFSocketRef sock = TCPClient;

  char test[] = "test\n\r";

  CFSocketContext CTX = { 0, test, NULL, NULL, NULL };

  // I enabled all types to see what was happening.
  TCPClient = CFSocketCreate(NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP,
                         kCFSocketConnectCallBack | kCFSocketReadCallBack | kCFSocketAcceptCallBack |kCFSocketDataCallBack|kCFSocketWriteCallBack,
                         (CFSocketCallBack)ConnectCallBack, &CTX);

  struct sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin_len = sizeof(addr);
  addr.sin_family = AF_INET;
  addr.sin_port = htons(PORT);
  inet_pton(AF_INET, "192.168.1.102", &addr.sin_addr.s_addr);
  CFDataRef connectAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr));

  CFSocketConnectToAddress(TCPClient, connectAddr, -1);

  CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, TCPClient, 0);
  CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes);
  CFRelease(sourceRef);
  CFRunLoopRun();

  /* Get on with our life, instead of waiting for a connect. */
  while(1) {
     struct timeval tv;
     tv.tv_usec = 0;
     tv.tv_sec = 1;
     select(-1, NULL, NULL, NULL, &tv);
  }
}


void ConnectCallBack(
                 CFSocketRef socket,
                 CFSocketCallBackType type,
                 CFDataRef address,
                 const void *data,
                 void *info)
{
  printf("CALLBACK TYPE: %d\n", type); // I only get 4 and 8 (once, sometimes twice)
  CFSocketNativeHandle sock = CFSocketGetNative(socket);

  char test[] = "test\n\r";

  CFSocketContext CTX = { 0, test, NULL, NULL, NULL };

  if (type == 4)
  {
    CFOptionFlags registeredEvents = kCFStreamEventOpenCompleted |
    kCFStreamEventHasBytesAvailable | kCFStreamEventCanAcceptBytes |
    kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred;

    CFStreamCreatePairWithSocket(kCFAllocatorDefault, sock,
                                 &readStream, &writeStream);  

    // Specify callbacks that will be handling stream events
    CFReadStreamSetClient(readStream, registeredEvents, readStreamEventHandler, &CTX);
    CFWriteStreamSetClient(writeStream, registeredEvents, writeStreamEventHandler, &CTX);

    // Schedule streams with current run loop
    CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(),
                                    kCFRunLoopCommonModes);
    CFWriteStreamScheduleWithRunLoop(writeStream, CFRunLoopGetCurrent(),
                                     kCFRunLoopCommonModes); 
    if ( ! CFReadStreamOpen(readStream) || ! CFWriteStreamOpen(writeStream)) {
      printf("DID NOT OPEN\n");
    } else {
      printf("OPEN!!!\n");      
    }
  }
}

For the stream callbacks, the only type I ever get back is type 1 (i.e. opened).

Am I missing something obvious?

Thanks, Ben