2

現在、チャットサーバーをプログラムしたいと考えています。しかし、ドキュメントを本当に理解するのに苦労しています。

現在、これは基本的に開発者ライブラリから抽出された私のコードです:

#import "ServerSide.h"

@implementation ServerSide

@synthesize socket;
@synthesize socketAddress;
@synthesize handleConnect;
@synthesize portNumber;

- (id)init{
    self = [super init];
    if (self) {
        self.socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, handleConnect, NULL);
    }
    return self;
}

- (void) bind {
    memset(&socketAddress, 0, sizeof(socketAddress));
    socketAddress.sin_len = sizeof(socketAddress);
    socketAddress.sin_family = AF_INET; /* Address family */
    socketAddress.sin_port = htons(self.portNumber); /* Or a specific port */
    socketAddress.sin_addr.s_addr= INADDR_ANY;

    CFDataRef sincfd = CFDataCreate(kCFAllocatorDefault, (UInt8 *)&socketAddress, sizeof(socketAddress));
    CFSocketSetAddress(socket, sincfd);
    CFRelease(sincfd);
}

- (void) listen {
    CFRunLoopSourceRef socketsource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), socketsource, kCFRunLoopDefaultMode);
    CFSocketGetNative(socket);
}

現在、「handleconnect」は初期化のない CFSocketCallBack ivar です。

今、他の人がソケットサーバーを作成するためにさまざまな実装を使用しているのを見てきましたが、これはドキュメントからのものであり、その上に構築したいと思います。

現在、サーバーに接続しようとしていますが、ソケットを開くことさえできないようです。telnet localhost 'port#' を使用して端末経由で接続できないようです。

クライアントの実装は次のとおりです。

#import "Client.h"

@implementation Client
@synthesize host;
@synthesize port;
@synthesize readStream;
@synthesize writeStream;
@synthesize inputStream;
@synthesize outputStream;

- (void)setup {

    NSLog(@"Setting up connection to %@ : %i", [[NSURL URLWithString:host] absoluteString], port);
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)[[NSURL URLWithString:host] host], port, &readStream, &writeStream);

    if(!CFWriteStreamOpen(writeStream)) {
        NSLog(@"Error, writeStream not open");
        return;
    }
}

- (void)open {
    NSLog(@"Opening streams.");

    inputStream = (__bridge_transfer NSInputStream *)readStream;
    outputStream = (__bridge_transfer NSOutputStream *)writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [inputStream open];
    [outputStream open];
}

- (void)close {
    NSLog(@"Closing streams.");

    [inputStream close];
    [outputStream close];

    [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [inputStream setDelegate:nil];
    [outputStream setDelegate:nil];

    inputStream = nil;
    outputStream = nil;
}

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event {
    NSLog(@"Stream triggered.");

    switch(event) {
        case NSStreamEventHasSpaceAvailable: {
            if(stream == outputStream) {
                NSLog(@"outputStream is ready.");
            }
            break;
        }
        case NSStreamEventHasBytesAvailable: {
            if(stream == inputStream) {
                NSLog(@"inputStream is ready.");

                uint8_t buf[1024];
                unsigned int len = 0;

                len = (int)[inputStream read:buf maxLength:1024];

                if(len > 0) {
                    NSMutableData* data=[[NSMutableData alloc] initWithLength:0];
                    [data appendBytes:(const void *)buf length:len];
                    [self readIn:[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]];
                    data = nil;
                }
            }
            break;
        }
        default: {
            NSLog(@"Stream is sending an Event: %lu", event);
            break;
        }
    }
}

- (void)readIn:(NSString *)s {
    NSLog(@"Reading in the following:");
    NSLog(@"%@", s);
}

- (void)writeOut:(NSString *)s {
    uint8_t *buf = (uint8_t *)[s UTF8String];

    [outputStream write:buf maxLength:strlen((char *)buf)];

    NSLog(@"Writing out the following:");
    NSLog(@"%@", s);
}


@end

指定したポートでサーバーを実行し、指定したホストとポート番号に接続するようにクライアントに指示します。

しかし、開いたソケットにデータを渡すにはどうすればよいですか...

大規模な説明は期待していませんが、この実装を進めるために何をする必要があるかについて、誰かがよりよく理解してくれれば、大いに感謝します。

4

0 に答える 0