2014-02-26 40 views
0

我創造插槽,並指定這樣的讀回調CFSocket越來越回調:其他CFSocketContexts

// SocketUser.m  

... 

- (void)run 
{ 
    CFSocketContext context = {0, (__bridge void *)(self), NULL, NULL, NULL}; 
    CFSocketRef socket = CFSocketCreateWithNative(NULL, fd, kCFSocketReadCallBack, SocketReadCallback, &context); 
} 

static void SocketReadCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) 
{ 
    SocketUser* obj = (__bridge SocketUser *) info; 

    [obj readData]; 
} 

- (void)readData 
{ 
    ... 
} 

在我的應用程序,也有發送ICMP報文SocketUser的多個實例(代碼是基於SimplePing源來自Apple)。

問題在於SocketUser的每個實例都爲SocketUser的每個實例接收一個讀回調。例如,如果我有5個實例並且其中一個實例接收到響應,則所有5個實例都會收到回調通知。可以檢查「info」參數,但我不明白爲什麼我會收到其他套接字上收到的數據的回調。我想我可以忽略除「自我」以外的任何情況下的回調,但我首先得到回調感到驚訝。

回答

1

每個TCP或UDP數據包都包含一個端口號,內核用它來識別哪個套接字應接收數據包的有效負載。

ICMP回顯迴應數據包不包含端口號。內核無法決定哪個套接字應該接收數據包,所以它只是將數據包發送到所有打開的ICMP套接字。因此,您的每個CFSocket實例都會收到該數據包,並且每個實例都會調用SocketReadCallback。沒有辦法避免這種情況。您的對象需要處理接收意外的ICMP數據包。

+0

謝謝。我知道ICMP不使用端口,但我想我只是錯誤地認爲內核會根據ICMP頭中的標識符字段進行匹配等等。我想我會自己使用標識符字段。感謝您的答覆。 – sbaker