2012-08-23 48 views
2

我们有以下代码连接到我们的服务器。这是iPhone应用程序的一部分。问题是recv(CFSocketGetNative(inSocketRef),& length,sizeof(length),0);在完成60秒后, 调用返回0。我们不会从服务器发送任何内容。我希望它等待数据或断开连接(服务器或客户端启动)。但是,它总是在60秒后返回。1分钟后iphone插槽断开

我在这里做错了什么?


void CallbackHandlerConnectionHandler(CFSocketRef inSocketRef, CFSocketCallBackType inType, 
       CFDataRef inAddress, const void *inData, void *inInfo) 
{ 

ChatServerConnectionHandler *conHandler = (ChatServerConnectionHandler *)inInfo; 

if([conHandler respondsToSelector:@selector(dataRecievedFromServer:)]) 
{ 
    int res = 0; 
    SInt32 length; 
    res = recv(CFSocketGetNative(inSocketRef), &length, sizeof(length), MSG_PEEK); 


    if(0 >= res || (length < 0)) 
    { 
     //Disconnect the connection, as some has occcured in the sockets.. 
     [conHandler performSelector:@selector(errorEncountered)]; 

     NSLog(@"Error occured in server!!"); 
     return; 
    } 


    printf ("good data") 
} 
} 

-(BOOL) connectToServer:(NSString *)ipAddress Port:(int)portNumber 
{  
connectionState = eConnectionEstablishInProgress; 
self.threadStopped = NO; 
CFRunLoopSourceRef source; 

int sockfd; 
struct sockaddr_in serv_addr; 

struct hostent *host; 
host = gethostbyname([ipAddress cStringUsingEncoding:NSUTF8StringEncoding]); 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
struct timeval timeout; 

if (sockfd < 0) 
{ 
    error("ERROR opening socket"); 
    connectionState = eNoConnection; 
    return NO; 
} 


bzero((char *) &serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
serv_addr.sin_port = htons(portNumber); 
serv_addr.sin_addr = *((struct in_addr *)host->h_addr); 
bzero(&(serv_addr.sin_zero),8); 


/* Creates a CFSocket object for a pre-existing native socket */ 
CFSocketContext socketContext={0,self,NULL,NULL,NULL}; 
socketRef = CFSocketCreateWithNative(kCFAllocatorDefault, 
             sockfd, 
             kCFSocketReadCallBack, 
             CallbackHandlerConnectionHandler, 
             &socketContext); 

source = CFSocketCreateRunLoopSource(NULL, socketRef, 0); 
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); 
CFRelease(source); 
source = nil; 

InstallSignalHandlers(); 

CFDataRef socketAddress; 
socketAddress = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *)&serv_addr, sizeof(serv_addr), kCFAllocatorNull); 
CFSocketError result=CFSocketConnectToAddress(socketRef, socketAddress, 0); 
CFRelease(socketAddress); 

if(kCFSocketSuccess == result) 
{ 
    //printf("Socket connection established"); 
    self.serverRunning = YES; 
    connectionState = eConnectionEstablised; 
    NSLog(@"\nCall Connection accepted callback."); 
    if([delegate respondsToSelector:@selector(conectionEstablishedWithTheServer)]) 
    { 
     [delegate performSelector:@selector(conectionEstablishedWithTheServer)]; 
    } 

} 
else 
{ 
    //printf("Unable to create socket why???***"); 
    connectionState = eNoConnection; 
    if(socketRef) 
     CFRelease(socketRef); 
    socketRef = nil; 
    return NO; 
} 

while(FALSE == self.threadStopped) 
{ 
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, FALSE); 
} 
NSLog(@"\nOut of Server socket connection thread."); 

self.serverRunning = NO; 


if([delegate respondsToSelector:@selector(conectionFinishedWithServer)]) 
{ 
    [delegate performSelector:@selector(conectionFinishedWithServer)]; 
} 

if(socketRef) 
{ 
    if(CFSocketIsValid(socketRef)) 
     CFSocketInvalidate(socketRef); 
} 


return YES; 
} 
+0

60秒后,我获得以下的分组(通过Wireshark的捕获) \t 68.092091000 122.248.244.87 \t \t 192.168.1.115 TCP \t \t 66 8475> 51930 [FIN,ACK] SEQ = 1 ACK = 1运= 5888 Len = 0 TSval = 261523689 TSecr = 764650529 –

回答

1

这看起来像一个服务器的问题 - 或者说功能:关闭闲置的连接,以保持足够的可用资源。

如果您没有编写服务器代码,请尝试联系作者。

您提到的数据包[FIN,ACK]是关闭您的套接字的数据包:您应该检查IP地址,但服务器最有可能是此数据包的发起者。

+1

我们发现了这个问题。服务器在AWS负载平衡器后面运行。每60秒后,如果连接空闲,负载均衡器会发送一个FIN。目前,我们已经停止使用负载平衡器。我们可能会建立一个定期的心跳解决方案来确保套接字不处于空闲状态。 –

+0

很高兴听到这一点。当您打算长时间保持连接时,“心跳解决方案”也是一个好主意。 –