Question

I created a TCP server using this (quite old) example by Apple. My server is up and running, listening on the specified Port for incoming connections.

Everything looks perfect, my client app can connect to the server and -stream:handleEvent: is called as expected.

But when I now write to the stream, the server kind of rejects my connection. The client says that 30 Bytes has been written successfully.

But my logs say:

did read 0 Bytes from inputStream.
data received: 
NSStreamEventErrorOccurred
Error: Error Domain=NSPOSIXErrorDomain code=14 "The operation couldn't be completed. Bad address"

In the client side I'm using following code to establish the connection:

CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"10.0.10.40", 58896, &readStream, &writeStream);

_iStream = (__bridge NSInputStream *)readStream;
_oStream = (__bridge NSOutputStream *)writeStream;

[_iStream setDelegate:self];
[_oStream setDelegate:self];

[_iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[_iStream open];
[_oStream open];

On the server side this creates the socket (a CFSocketCallBack is provided)

_IPv4Socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, (CFSocketCallBack)&JWTCPServerAcceptCallBack, nil);

Then in the callback I'm pairing using this:

CFStreamCreatePairWithSocket(kCFAllocatorDefault, nativeSocketHandle, &readStream, &writeStream);
CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);

And then bridge cast the streams to NSStreams, set the delegate, schedule in in current runloop and open them.

I'm not quite sure why this can happen so I don't provide the whole server code here. It would be simply too much.

When you need a specific piece of code or guess where it could be caused, I'll post the respective code here.

UPDATE

I now did a lot of research in my own code. I tracked the issue down to my -stream:handleEvent method invocation.

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
    uint8_t *buffer = NULL;
    NSMutableData *receivedData;

    switch(eventCode) {
        case NSStreamEventHasBytesAvailable:

        if(aStream == _iStream) {
            receivedData = [NSMutableData data];

            while([_iStream read:buffer maxLength:1] > 0) {
            //    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ THIS RETURNS -1
                if([[[NSString alloc] initWithBytes:buffer length:sizeof(buffer) encoding:NSUTF8StringEncoding] isEqualToString:@"\n"]) {
                    break;
                }

                [receivedData appendBytes:buffer length:sizeof(buffer)];
            }

             NSLog(@"Did receive %li Bytes of data: %@", [receivedData length], [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding]);
        } 
    }
}

UPDATE 2

I read this great Apple Article about TCP Servers and clients. I walked through all the steps and my program is almost identical with the code provided by Apple. The problem remains.

Was it helpful?

Solution

I found the solution! Actually I was declaring the buffer completely wrong. So the address meant by the error message wasn't a network address, as I thought...

uint8_t *buffer = NULL;

must be turned into

uint8_t buffer[1];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top