简体   繁体   English

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

[英]NSInputStream can't read from TCP Connection [TCP-Server]

I created a TCP server using this (quite old) example by Apple . 我使用Apple的这个(相当古老的)示例创建了一个TCP服务器。 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. 一切看起来都很完美,我的客户端应用程序可以连接到服务器,并且-stream:handleEvent:可以按预期方式调用。

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. 客户端说成功写入了30个字节。

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) 在服务器端,这将创建套接字(提供了CFSocketCallBack)

_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. 然后桥接将流转换为NSStreams,设置委托,在当前运行循环中计划并打开它们。

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 UPDATE

I now did a lot of research in my own code. 我现在用自己的代码做了很多研究。 I tracked the issue down to my -stream:handleEvent method invocation. 我将问题归结为-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]);
        } 
    }
}

UPDATE 2 更新2

I read this great Apple Article about TCP Servers and clients. 我读了这篇有关TCP服务器和客户端的Apple优秀文章 I walked through all the steps and my program is almost identical with the code provided by Apple. 我完成了所有步骤,程序几乎与Apple提供的代码相同。 The problem remains. 问题仍然存在。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM