2011-11-22 4 views
1

호스트에 연결하는 동안 내 응용 프로그램 시간이 초과되었습니다. 시간 제한 시간은 무제한으로 설정되어있어서 클라이언트가 실제로 연결할 수없는 경우에만 사용할 수 있습니다.asyncsocket ipad가 서버에 연결하지 않습니다.

asyncsockets를 실행하는 iPad 응용 프로그램이 있는데 비동기 소켓을 사용하여 바탕 화면의 서버에 연결하려고합니다. iPad는 특히 iOS 5이며 GCD 비동기 소켓을 사용합니다.

서버가 NSRunLoop을 통해 호출되고 있습니다. 클라이언트로부터 어떠한 형태의 연결도받지 못합니다 (중단 점이 텔넷 연결처럼 잡히지 않습니다).

다른 컴퓨터에서 텔넷으로 서버에 연결할 수 있습니다. 또한 iPad 클라이언트를 호스트에 연결할 수 있습니다. google.com (포트 80) : 괜찮습니다.

저는 8080, 4500 및 50000 포트의 서버에 iPad를 연결하려고 시도했지만 모두 성공하지 못했습니다 (모두 텔넷에서 작동합니다).

나는이 문제를 일으키는 서버 코드에 뭔가가 있다고 생각하지만 확실하지 않습니다. 여기

https://github.com/robbiehanson/CocoaAsyncSocket/blob/master/Examples/GCD/SimpleHTTPClient/Mobile/SimpleHTTPClient/SimpleHTTPClientAppDelegate.m 내 서버 코드 : http://mysterycoconut.com/blog/2010/07/tweak-away/

내 클라이언트 코드가 asyncsockets 저장소에서 제공하는 샘플 GCD 코드에서 HTTP 클라이언트 코드를 수정 :

내 서버 코드가 검색 샘플에서입니다

- (id) init 
{ 
    if (self = [super init]) { 
    // AsyncSocket optionally uses the Lumberjack logging framework. 
    // 
    // Lumberjack is a professional logging framework. It's extremely fast and flexible. 
    // It also uses GCD, making it a great fit for GCDAsyncSocket. 
    // 
    // As mentioned earlier, enabling logging in GCDAsyncSocket is entirely optional. 
    // Doing so simply helps give you a deeper understanding of the inner workings of the library (if you care). 
    // You can do so at the top of GCDAsyncSocket.m, 
    // where you can also control things such as the log level, 
    // and whether or not logging should be asynchronous (helps to improve speed, and 
    // perfect for reducing interference with those pesky timing bugs in your code). 
    // 
    // There is a massive amount of documentation on the Lumberjack project page: 
    // https://github.com/CocoaLumberjack/CocoaLumberjack 
    // 
    // But this one line is all you need to instruct Lumberjack to spit out log statements to the Xcode console. 

    [DDLog addLogger:[DDTTYLogger sharedInstance]]; 

    // Create our GCDAsyncSocket instance. 
    // 
    // Notice that we give it the normal delegate AND a delegate queue. 
    // The socket will do all of its operations in a background queue, 
    // and you can tell it which thread/queue to invoke your delegate on. 
    // In this case, we're just saying invoke us on the main thread. 
    // But you can see how trivial it would be to create your own queue, 
    // and parallelize your networking processing code by having your 
    // delegate methods invoked and run on background queues. 

    asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()]; 

    // Now we tell the ASYNCHRONOUS socket to connect. 
    // 
    // Recall that GCDAsyncSocket is ... asynchronous. 
    // This means when you tell the socket to connect, it will do so ... asynchronously. 
    // After all, do you want your main thread to block on a slow network connection? 
    // 
    // So what's with the BOOL return value, and error pointer? 
    // These are for early detection of obvious problems, such as: 
    // 
    // - The socket is already connected. 
    // - You passed in an invalid parameter. 
    // - The socket isn't configured properly. 
    // 
    // The error message might be something like "Attempting to connect without a delegate. Set a delegate first." 
    // 
    // When the asynchronous sockets connects, it will invoke the socket:didConnectToHost:port: delegate method. 

    NSError *error = nil; 

#if USE_SECURE_CONNECTION 
    uint16_t port = 443; // HTTPS 
#else 
    uint16_t port = 8080; // HTTP 
#endif 

    DDLogVerbose(@"port: %d\t host: %@",port,@"130.85.92.12"); 

    if (![asyncSocket connectToHost:@"130.85.92.12" onPort:port error:&error]) 
    { 
     DDLogError(@"Unable to connect to due to invalid configuration: %@", error); 
    } 
    else 
    { 
     DDLogVerbose(@"Connecting..."); 
    } 

#if USE_SECURE_CONNECTION 

    // The connect method above is asynchronous. 
    // At this point, the connection has been initiated, but hasn't completed. 
    // When the connection is establish, our socket:didConnectToHost:port: delegate method will be invoked. 
    // 
    // Now, for a secure connection we have to connect to the HTTPS server running on port 443. 
    // The SSL/TLS protocol runs atop TCP, so after the connection is established we want to start the TLS handshake. 
    // 
    // We already know this is what we want to do. 
    // Wouldn't it be convenient if we could tell the socket to queue the security upgrade now instead of waiting? 
    // Well in fact you can! This is part of the queued architecture of AsyncSocket. 
    // 
    // After the connection has been established, AsyncSocket will look in it's queue for the next task. 
    // There it will find, dequeue and execute our request to start the TLS security protocol. 
    // 
    // The options passed to the startTLS method are fully documented in the GCDAsyncSocket header file. 
    // The deusty server only has a development (self-signed) X.509 certificate. 
    // So we tell it not to attempt to validate the cert (cause if it did it would fail). 

    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] 
                 forKey:(NSString *)kCFStreamSSLValidatesCertificateChain]; 

    [asyncSocket startTLS:options]; 

#endif 
    } 

    return self; 
} 

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port 
{ 
    DDLogVerbose(@"socket:didConnectToHost:%@ port:%hu", host, port); 

    // HTTP is a really simple protocol. 
    // 
    // If you don't already know all about it, this is one of the best resources I know (short and sweet): 
    // http://www.jmarshall.com/easy/http/ 
    // 
    // We're just going to tell the server to send us the metadata (essentially) about a particular resource. 
    // The server will send an http response, and then immediately close the connection. 

    NSString *msg = @"iOS client connected\r\n\r\n"; 
    NSData *msgdata = [msg dataUsingEncoding:NSUTF8StringEncoding]; 

    [asyncSocket writeData:msgdata withTimeout:-1.0 tag:0]; 

    // Side Note: 
    // 
    // The AsyncSocket family supports queued reads and writes. 
    // 
    // This means that you don't have to wait for the socket to connect before issuing your read or write commands. 
    // If you do so before the socket is connected, it will simply queue the requests, 
    // and process them after the socket is connected. 
    // Also, you can issue multiple write commands (or read commands) at a time. 
    // You don't have to wait for one write operation to complete before sending another write command. 
    // 
    // The whole point is to make YOUR code easier to write, easier to read, and easier to maintain. 
    // Do networking stuff when it is easiest for you, or when it makes the most sense for you. 
    // AsyncSocket adapts to your schedule, not the other way around. 

#if READ_HEADER_LINE_BY_LINE 

    // Now we tell the socket to read the first line of the http response header. 
    // As per the http protocol, we know each header line is terminated with a CRLF (carriage return, line feed). 

    [asyncSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1.0 tag:0]; 
#else 

    // Now we tell the socket to read the full header for the http response. 
    // As per the http protocol, we know the header is terminated with two CRLF's (carriage return, line feed). 

    [asyncSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1.0 tag:0]; 

#endif 
} 

- (void)socketDidSecure:(GCDAsyncSocket *)sock 
{ 
    // This method will be called if USE_SECURE_CONNECTION is set 

    DDLogVerbose(@"socketDidSecure:"); 
} 

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag 
{ 
    DDLogVerbose(@"socket:didWriteDataWithTag:"); 
} 

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 
{ 
    DDLogVerbose(@"socket:didReadData:withTag:"); 

    NSString *httpResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

    NSLog(@"%@",httpResponse); 

#if READ_HEADER_LINE_BY_LINE 

    DDLogInfo(@"Line httpResponse: %@", httpResponse); 

    // As per the http protocol, we know the header is terminated with two CRLF's. 
    // In other words, an empty line. 

    if ([data length] == 2) // 2 bytes = CRLF 
    { 
     DDLogInfo(@"<done>"); 
    } 
    else 
    { 
     // Read the next line of the header 
     [asyncSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1.0 tag:0]; 
    } 

#else 

    DDLogInfo(@"Full httpResponse: %@", httpResponse); 

#endif 

    [httpResponse release]; 
} 

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err 
{ 
    // Since we requested HTTP/1.0, we expect the server to close the connection as soon as it has sent the response. 

    DDLogVerbose(@"socketDidDisconnect:withError: \"%@\"", err); 
} 
,369 : 여기
- (id) init; 
{ 
    self = [super init]; 
    if (self != nil) 
    { 
     debugServer = [[AsyncSocket alloc] initWithDelegate:self]; 
     connectedClients = [[NSMutableArray alloc] initWithCapacity:1]; 
     running = false; 
    } 
    return self; 
} 

- (void) dealloc; 
{ 
    [self stop]; 
    [connectedClients release]; 
    [debugServer release]; 
    [super dealloc]; 
} 

- (void) startOnPort 
{ 
    if (running) return; 

    if (_port < 0 || _port > 65535) 
     _port = 0; 

    NSError *error = nil; 
    if (![debugServer acceptOnPort:_port error:&error]) 
     return; 

    NSLog(@"My Awesome Debug Server has started on port %hu", [debugServer localPort]); 

    running = true; 
} 


- (void) stop; 
{ 
    if (!running) return; 

    [debugServer disconnect]; 
    for (AsyncSocket* socket in connectedClients) 
     [socket disconnect]; 

    running = false; 
} 


- (void) setPort:(int)in_port{ 
    _port = in_port; 
} 

- (void)onSocket:(AsyncSocket *)socket didAcceptNewSocket:(AsyncSocket *)newSocket; 
{ 
    [connectedClients addObject:newSocket]; 
} 


- (void)onSocketDidDisconnect:(AsyncSocket *)socket; 
{ 
    [connectedClients removeObject:socket]; 
} 

- (void)onSocket:(AsyncSocket *)socket didConnectToHost:(NSString *)host port:(UInt16)port; 
{ 
    NSLog(@"Accepted client %@:%hu", host, port); 

    NSData *welcomeData = [@"Welcome to my Awesome Debug Server\r\n\r\n" 
          dataUsingEncoding:NSUTF8StringEncoding]; 
    [socket writeData:welcomeData withTimeout:-1 tag:WelcomeMsgTag]; 

    [socket readDataWithTimeout:-1 tag:GenericMsgTag]; 
} 


- (void)onSocket:(AsyncSocket *)socket didReadData:(NSData *)data withTag:(long)tag; 
{ 
    NSString *tmp = [NSString stringWithUTF8String:[data bytes]]; 
    NSString *input = [tmp stringByTrimmingCharactersInSet: 
         [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 

    NSLog(@"%@",input); 

    if ([input isEqualToString:@"exit"]) 
    { 
     NSData *byeData = [@"Bye!\r\n" dataUsingEncoding:NSUTF8StringEncoding]; 
     [socket writeData:byeData withTimeout:-1 tag:GenericMsgTag]; 
     [socket disconnectAfterWriting]; 
     return; 
    } 

    [socket readDataWithTimeout:-1 tag:GenericMsgTag]; 
} 

@end 

... 그리고 내 클라이언트 코드

나는 대답을 둘러 보았지만 성공을 거두지 못했습니다. 나는 최선의 행동 방침은 내 두뇌를 찢어서 직접 풀어주기보다는 모든 것을 요구하는 것이라고 생각했다.

답변

1

해결책은 로컬 네트워크에 다르게 연결하는 것이 었습니다. 로컬 액세스를 위해 로그인해야하지만 WAN (Wide Area Network) 액세스를 위해 "방문자"연결을 제공해야하는 네트워크로 작업하고있었습니다. 장치 (iPad)가 자동으로 "방문자"로 연결되었으므로 수동으로 로그인해야했습니다.

그렇다면이 API를 사용하여 연결할 수없는 경우 네트워크 연결 방법을 확인하십시오.

관련 문제