2012-08-23 5 views
2

다음 코드는 우리 서버에 연결하기위한 것입니다. 이것은 iPhone App의 일부입니다.1 분 후에 아이폰 소켓이 끊어졌습니다.

문제는 recv (CFSocketGetNative (inSocketRef), & 길이, sizeof (길이), 0)입니다. 호출은 정확히 60 초 후에 0을 반환합니다. 서버에서 아무것도 보내지 않습니다. 데이터 또는 연결 끊기 (서버 또는 클라이언트 시작)를 기다려야합니다. 그러나 60 초 후에 항상 반환됩니다.

내가 뭘 잘못하고 있니?


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 초 후, I는 (Wireshark를 통해 캡쳐 된) 패킷
966 68.092091000 \t \t \t 122.248.244.87 192.168.1.115 TCP \t \t \t 66 8,475> 51,930 [FIN, ACK 서열 긍정 = 1 = 1 승 = 5888에 따라 얻을 Len = 0 TSval = 261523689 TSecr = 764650529 –

답변

1

이것은 서버 문제처럼 보인다 - 또는 오히려 기능 : 충분한 자원을 유지하기 위해 비활성 연결을 닫는.

서버 코드를 작성하지 않은 경우 작성자에게 문의하십시오.

[FIN, ACK]로 표시된 패킷은 소켓을 닫는 패킷입니다. IP 주소를 확인해야하지만 서버가이 패킷의 개시 자일 가능성이 큽니다.

+1

우리가 문제를 발견했습니다. 서버는 AWS로드 밸런서 뒤에서 실행됩니다. 60 초마다 연결이 유휴 상태이면로드 밸런서가 FIN을 전송합니다. 당분간로드 밸런서 사용이 중단되었습니다. 우리는 아마도 소켓이 유휴 상태가 아닌지 확인하기 위해주기적인 하트 비트 솔루션을 구축 할 것입니다. –

+0

반가워요. 또한 '하트 비트 솔루션'은 연결을 더 오랫동안 유지하려는 경우 좋은 아이디어입니다. –

관련 문제