2013-02-07 88 views
1

我想知道我的服務器是否通過我的ios應用程序聯機。下面是我在做什麼:ios - 確定某個端口的某個地址是否可達

Boolean result; 
CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault, (__bridge CFDataRef)(serverIPAddress)); //serverIPAdress = "10.10.10.100:5010" 

    if(hostRef) { 
     result = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL); // pass an error instead of NULL here to find out why it failed 
    } 

    if (!result) { //This means that the host was unreachable   
     return ; 
    } 

我的服務器是在網上,我可以在以後訪問它的代碼(這意味着我與服務器的連接工作完全正常)。但是,我希望能夠檢測到某個端口上的服務器是否可以訪問。

另外,如果我刪除「:5010」從IP地址,它檢測到我的服務器在線(它不會在「!result」條件去),並檢測,如果我把「10.10.10.253我的服務器脫機「這對應於我的網絡上沒有IP地址。

我該如何設法確定我的服務器是否在線?

我看這個問題:Reachability with Address - Server AND Port - iOS 5但它不工作,因爲它總是返回,這是可達無論什麼IP地址,我進入提前

感謝

+0

查看以下鏈接套接字連接阻止用戶界面:http://stackoverflow.com/questions/6329723/ios-sdk-how-can-i-check-if-a-port-is-open - 我想用下面的庫:https://github.com/robbiehanson/CocoaAsyncSocket –

回答

0

一種方法可能是打開到特定端口的套接字連接以查看是否收到任何響應。如果不是,則目的地不可達。例如

#include <arpa/inet.h> //for PF_INET, SOCK_STREAM, IPPROTO_TCP etc 

CFRunLoopSourceRef gSocketSource; 
void ConnectCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) 
{ 
    UInt8 buffer[1024]; 
    bzero(buffer, sizeof(buffer)); 
    CFSocketNativeHandle sock = CFSocketGetNative(socket); // The native socket, used recv() 

    //check here for correct connect output from server 
    recv(sock, buffer, sizeof(buffer), 0); 
    printf("Output: %s\n", buffer); 

    if (gSocketSource) 
    { 
     CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent(); 
     if (CFRunLoopContainsSource(currentRunLoop, gSocketSource, kCFRunLoopDefaultMode)) 
     { 
      CFRunLoopRemoveSource(currentRunLoop, gSocketSource, kCFRunLoopDefaultMode); 
     } 
     CFRelease(gSocketSource); 
    } 

    if (socket) //close socket 
    { 
     if (CFSocketIsValid(socket)) 
     { 
      CFSocketInvalidate(socket); 
     } 
     CFRelease(socket); 
    } 
} 

void ConnectSocket() 
{ 
    //socket 
    CFSocketContext context = {0, NULL, NULL, NULL, NULL}; 
    CFSocketRef theSocket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketConnectCallBack , (CFSocketCallBack)ConnectCallBack, &context); 

    //address 
    struct sockaddr_in socketAddress; 
    memset(&socketAddress, 0, sizeof(socketAddress)); 
    socketAddress.sin_len = sizeof(socketAddress); 
    socketAddress.sin_family = AF_INET; 
    socketAddress.sin_port = htons(5010); 
    socketAddress.sin_addr.s_addr = inet_addr("10.10.10.253"); 

    gSocketSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, theSocket, 0); 
    CFRunLoopAddSource(CFRunLoopGetCurrent(), gSocketSource, kCFRunLoopDefaultMode); 

    CFDataRef socketData = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)&socketAddress, sizeof(socketAddress)); 
    CFSocketError status = CFSocketConnectToAddress(theSocket, socketData, 30); //30 second timeout 
    //check status here 
    CFRelease(socketData); 
} 

基本上,如果服務器在該端口不可達,你將最有可能獲得kCFSocketTimeout爲CFSocketError狀態。如果您正在尋找解析服務器返回的特定響應以確定服務器是否準備就緒,ConnectCallBack函數將在成功套接字連接時調用。

這只是一個簡單的例子,確保不通過調用主線程如的recv()

相關問題