2014年9月24日 星期三

socket on mac

需要定義callback function
在callback function裏面再分別註冊讀或寫的callback function
server使用CFSocketCreate產生,裏面註冊accept callback
接下來設定參數
/* 設定通訊埠和位址 */
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));             //memset函數對特殊的位址進行記憶體覆制
    addr.sin_len = sizeof(addr);
    addr.sin_family = AF_INET;                  //AF_INET是設定 IPv4
    addr.sin_port = htons(PORT);                //htons函數 無號短整數數轉換成網路位元組序
    addr.sin_addr.s_addr = htonl(INADDR_ANY);   //INADDR_ANY有核心分配,htonl函數 無號長整數數轉換成網路位元組序
    
    /* 從指定位元組緩沖區複製,一個不可變的CFData物件*/
    CFDataRef address = CFDataCreate(kCFAllocatorDefault, (UInt8*)&addr, sizeof(addr));
    
    /* 設定Socket*/
    if (CFSocketSetAddress(sserver, (CFDataRef)address) != kCFSocketSuccess) {
        fprintf(stderr, "Socket綁定失敗\n");
        CFRelease(sserver);
        return -1;
    }
接著建立runloop
/* 建立一個Run Loop Socket */
    CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, sserver, 0);
    /* Socket源新增到Run Loop */
    CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes);
    CFRelease(sourceRef);
    
    printf("Socket listening on port %d\n", PORT);
    /* 執行Loop */
    CFRunLoopRun();
在accept callback中建立stream pipe
/* 建立讀寫Socket */
    CFStreamCreatePairWithSocket(kCFAllocatorDefault, sock,
                                 &readStream, &writeStream);
    
    if (!readStream || !writeStream) {
        close(sock);
        fprintf(stderr, "CFStreamCreatePairWithSocket() 失敗\n");
        return;
    }

建立用戶端物件及callback以及runloop
CFStreamClientContext streamCtxt = {0, NULL, NULL, NULL, NULL};
    // 登錄兩種回調函數
    CFReadStreamSetClient(readStream, kCFStreamEventHasBytesAvailable, ReadStreamClientCallBack, &streamCtxt);
    CFWriteStreamSetClient(writeStream, kCFStreamEventCanAcceptBytes, WriteStreamClientCallBack, &streamCtxt);
    
    //加入到循環當中
    CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(),kCFRunLoopCommonModes);
    CFWriteStreamScheduleWithRunLoop(writeStream, CFRunLoopGetCurrent(),kCFRunLoopCommonModes);
    
    CFReadStreamOpen(readStream);
    CFWriteStreamOpen(writeStream);




沒有留言:

張貼留言