在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);
沒有留言:
張貼留言