2

currently I am wanting to program a chat server. I am having trouble really understanding the documentations though.

Currently, this is my code, basically extracted from the developer library:

#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);
}

Now, 'handleconnect' is a CFSocketCallBack ivar with no initialization.

Now I have seen others use different implementations to creating a socket server but this was the one from the docs and I would like to build on top of that.

I am currently attempting to connect to the server but it looks like this doesn't even open a socket. I can't seem to connect to it through terminal using telnet localhost 'port#' either.

Heres the client implementation:

#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

I run the server on a specified port, then tell the client to connect to the specified host and port number.

But now how do I pass data in the socket I have opened...

I don't expect some large explanation, but if someone could give me a better understanding of what needs to be done to further this implementation, I'd greatly appreciate it.

4

0 回答 0