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 にブリッジ キャストし、デリゲートを設定し、現在の実行ループでスケジュールして、それらを開きます。
なぜこれが起こるのかよくわからないので、ここではサーバー コード全体を提供しません。それは単に多すぎるでしょう。
特定のコードが必要な場合、またはそれがどこで発生したかを推測する場合は、それぞれのコードをここに投稿します。
アップデート
私は今、自分のコードで多くの調査を行いました。-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 サーバーとクライアントに関するApple のすばらしい記事を読みました。すべての手順を実行しましたが、私のプログラムは Apple から提供されたコードとほとんど同じです。問題は残ります。