3 Replies
      Latest reply on Mar 13, 2019 2:59 AM by eskimo
      itang Level 1 Level 1 (0 points)

        When the function CFSocketConnectToAddress return kCFSocketError, I only know that the connection failed, I don't know why. I want to know why the connection fails.

        I know if I pass a negative value to the timeout parameter, I can receive the error code in kCFSocketConnectCallBack when CFSocketConnectToAddress failed. But I must pass a positive value to the timeout parameter, because I want to limit connection time.

        If you know how, tell me please. Thanks.

        • Re: When the function CFSocketConnectToAddress return kCFSocketError, how to get error reason, such as "not connected to Internet"?
          eskimo Apple Staff Apple Staff (10,835 points)

          Why are you using CFSocket?

          CFSocket is effectively an implementation detail of higher-level APIs.  Back in the day, there were some specific situations where CFSocket was the only way to achieve some certain goals (like integrating UDP with the runloop, or listening for incoming connections), but these days that’s no longer the case.  I can’t think of any situation where CFSocket is the right answer any more, and you’ll have an easier time of things if you avoid it entirely.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: When the function CFSocketConnectToAddress return kCFSocketError, how to get error reason, such as "not connected to Internet"?
              itang Level 1 Level 1 (0 points)

              Thank your answer.

              I am trying to use CFStream to connect a server, as follows.

              Now, I encountered two problems:

              1. I do not know how to set timeout. When using CFSocket, I set timeout like this: CFSocketConnectToAddress(self.socket, sin_cfd, 3);

              2. I do not know how to close the connection. I used the following method closeConnection to close the connection, although the connection is successfully closed but the subthread is not released.

               

              Could you help me resovle the two problems ?

              Thanks !

               

              - (void)start
              {
                  NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(connectOnSubthread) object:nil];
                  [thread start];
              }
              
              - (void)connectOnSubthread
              {
                  CFReadStreamRef readStream;
                  CFWriteStreamRef writeStream;
                  CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)_domain, _port, &readStream, &writeStream);
                  
                  CFReadStreamSetProperty(readStream,  kCFStreamPropertyShouldCloseNativeSocket,  kCFBooleanTrue);
                  CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
                  
                  _inputStream = (__bridge NSInputStream *)readStream;
                  _outputStream = (__bridge NSOutputStream *)writeStream;
                  
                  _inputStream.delegate = self;
                  _outputStream.delegate = self;
              
                  [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
                  [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
                  
                  [_inputStream open];
                  [_outputStream open];
                  
                  [[NSRunLoop currentRunLoop] run];
              }

               

              - (void)closeConnection
              {
                  [_inputStream close];
                  [_outputStream close];
                  _inputStream = nil;
                  _outputStream = nil;
              }
                • Re: When the function CFSocketConnectToAddress return kCFSocketError, how to get error reason, such as "not connected to Internet"?
                  eskimo Apple Staff Apple Staff (10,835 points)

                  First up, don’t use CFSocket for outgoing TCP connections.  While CFSocket was useful in some corner cases back in the day, it’s never been the right option for outgoing TCP connections.

                  Next, CFSocketStream does not have a connection timeout function, but that’s not strictly speaking necessary.  You can implement your own timeout using NSTimer.  That is, schedule your streams to run asynchronously on the run loop, and schedule a timeout timer on that same run loop.  If the connection succeeds before the timer fires, cancel the timer.  If the timer fires before the connection succeeds, cancel the connection.

                  Finally, with regards the code you posted, you’re creating a separate thread to run your connection.  This is generally not a good idea.  Threads are relatively expensive, so it’s best to schedule all of your connections on the same thread.  The easiest option is to use the main thread for this.  This is convenient and safe as long as your stream event handler doesn’t block for too long.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"