NSInputStream无法从TCP连接读取[TCP-Server]

时间:2013-07-25 13:43:20

标签: sockets tcp nsstream nsinputstream nsoutputstream

我使用this (quite old) example by Apple创建了一个TCP服务器。我的服务器已启动并正在运行,在指定的端口上侦听传入连接。

一切看起来都很完美,我的客户端应用可以连接到服务器并按预期调用-stream:handleEvent:

但是当我现在写入流时,服务器拒绝我的连接。客户说已成功写入30字节。

但我的日志说:

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

在客户端,我使用以下代码建立连接:

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];

在服务器端,这将创建套接字(提供CFSocketCallBack)

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

然后在回调中我使用它进行配对:

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

然后桥接将流转换为NSStreams,设置委托,在当前的runloop中安排并打开它们。

我不太清楚为什么会发生这种情况所以我不在这里提供整个服务器代码。这太简单了。

当您需要特定的代码或猜测可能导致的代码时,我会在此处发布相应的代码。

更新

我现在在自己的代码中做了很多研究。我将问题跟踪到我的-stream:handleEvent方法调用。

- (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]);
        } 
    }
}

更新2

我阅读了有关TCP服务器和客户端的this great Apple Article。我完成了所有步骤,我的程序几乎与Apple提供的代码相同。问题依然存在。

1 个答案:

答案 0 :(得分:2)

我找到了解决方案!实际上我声明缓冲区是完全错误的。因此,错误消息所指的地址不是网络地址,正如我想的那样......

uint8_t *buffer = NULL;

必须变成

uint8_t buffer[1];