我想知道我的服务器是否通过我的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 ;
}
我的服务器在线,我可以稍后在代码中访问它(这意味着我与服务器的连接工作正常)。但是,我希望能够检测某个端口上的服务器是否可访问。
另外,如果我从ip地址中删除“:5010
”,它会检测到我的服务器在线(它没有进入“!result
”状态)并检测到我的服务器如果我将“10.10.10.253
”对应于我网络上的无IP地址,则处于脱机状态。
如何确定我的服务器是否在线?
我看过这个问题:Reachability with Address - Server AND Port - iOS 5但它不起作用,因为无论我输入什么IP地址,它总是返回它是可以访问的
提前致谢
答案 0 :(得分:1)
一种方法可能是打开与特定端口的套接字连接,以查看是否收到任何响应。如果没有,则目的地无法到达。例如
#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);
}
基本上,如果服务器在该端口无法访问,您很可能会获得CFSocketError状态的kCFSocketTimeout。如果您希望从服务器解析特定响应以确定服务器是否准备就绪,则在成功连接套接字时将调用ConnectCallBack函数。
这只是一个简单的例子,请确保不要通过调用主线程上的套接字连接来阻止UI,例如recv()