2012-08-23 52 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

很高興聽到這一點。當您打算長時間保持連接時,「心跳解決方案」也是一個好主意。 –