2012-03-14 43 views
0

我有一個作爲服務器運行的.NET桌面程序,我試圖在iOS中實現我的客戶端程序的端口,但是我從NSSocket獲得了一些奇怪的行爲。這是來自服務器的相關代碼。iOS和.NET之間的套接字問題?

public NetworkListener() 
{ 
    _Stream = new MemoryStream(); 
    _tcpServer = new TcpListener(System.Net.IPAddress.Any, 8086); 
    _endPoints = new List<EndPoint>(); 
} 

public void BeginListening() 
{ 
    _tcpServer.Start(); 
    _workerThread = new Thread(new ThreadStart(WorkerLoop)); 
    _workerThread.IsBackground = true; 
    _workerThread.Start(); 
} 

private void WorkerLoop() 
{ 
    while(true) 
    { 
     _clientSocket = _tcpServer.AcceptSocket(); 
     _networkStream = new NetworkStream(_clientSocket, true); 
     /* ... rest of method here ... */ 
    } 
} 

我試圖在iOSSimulator下面的代碼使用的XCode 4.2和定位從代管模擬器是在同一個網絡服務器程序上,我可以運行使用Java客戶端的iOS 5的Mac與下面相同的硬編碼本地IP連接就好了。在Objective C代碼中,我收到一些數據並將其存儲在一個NSData成員屬性中,然後一旦打開Socket,我就使用流回調告訴我何時嘗試發送數據。

- (IBAction)connectToServer 
{ 
    NSURL *serverUrl = [NSURL URLWithString:@"10.0.0.5"]; 

    CFReadStreamRef readStream; 
    CFWriteStreamRef writeStream; 
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)[serverUrl host], 8086, &readStream, &writeStream); 

    [self setInStream:(NSInputStream *)readStream]; 
    [self setOutStream:(NSOutputStream *)writeStream]; 
    [self.inStream setDelegate:self]; 
    [self.outStream setDelegate:self]; 
    [self.inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [self.outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [self.inStream open]; 
    [self.outStream open]; 

    NSError *error = [self.outStream streamError]; 
    if (error) { 
     NSLog(@"outstream error: %@", [error localizedDescription]); 
    } 
} 

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode 
{ 
    NSError *error; 
    if ([aStream isEqual:outStream]) { 
     switch (eventCode) { 
      case NSStreamEventHasSpaceAvailable: 
       NSLog(@"Stream has space!"); 
       [self writeDataToStream]; 
       break; 
      case NSStreamEventOpenCompleted: 
       NSLog(@"Stream is open!"); 
       break; 
      case NSStreamEventErrorOccurred: 
       error = [self.outStream streamError]; 
       NSLog(@"Stream error occured: %@", [error localizedDescription]); 
       break; 
      default: 
       break; 
     } 
    } 
} 

- (void)writeDataToStream 
{ 
    unsigned int byteIndex = 0; 
    unsigned int length = data.length; 
    uint8_t *buffer = (uint8_t *)[data bytes]; 

    while (byteIndex <= length) {  
     unsigned int bufferLength = (length - byteIndex >= 1024) ? 1024 : (length - byteIndex); 
     uint8_t tempBuffer[bufferLength]; 

     (void)memcpy(tempBuffer, buffer, bufferLength); 
     if (self.outStream.hasSpaceAvailable) { 
      bufferLength = [self.outStream write:tempBuffer maxLength:bufferLength]; 
      byteIndex += bufferLength; 
     } else 
      NSLog(@"Stream is blocked!"); 
    } 
} 

在Xcode控制檯中,我看到「流是開放的!」,其次是「流具有空間!」,其次是說,一個異常「的操作無法完成。錯誤的文件描述符」。我在_tcpServer.AcceptSocket()之後立即在我的服務器代碼中放置了一個斷點,但它從來沒有命中。似乎流打開,但套接字永遠不會連接?

+0

你沒有指出,但你是否一步一步來看看你是否真的寫了任何東西到插座?如果你沒有,那麼你的bufferLength變量變成-1。然後這將會持續循環(因爲byteIndex永遠不會超過長度!在某些時候,你的(長度 - 字節索引)將小於1,並且這是我懷疑事情正在扔餅乾的地方。 – 2012-04-20 14:06:46

+0

幫助網絡應用程序的另一件事是運行一個數據包嗅探器(wireshark甚至CocoaPacketAnalyzer)幫助非常大,然後你不必猜測爲什麼事情不起作用。 – 2012-04-20 14:08:54

回答

-1

嘗試檢查[serverUrl主機]是否爲零。

我也遇到過這個問題,所以我在IP地址(URLWithString:@"http://10.0.0.5")之前加了一個http://協議字符串。

+0

他沒有使用http協議。所以,不需要添加http前綴。 – fyasar 2013-04-06 14:24:04

+0

我只是簡單地指向在NSURL中可能會出現錯誤爲零的錯誤(參考:developer.apple.com/library/mac/#documentation/Cocoa/Reference/...「處理對象創建失敗」一節,您需要符合RFC 2396爲文件路徑或RFC 1808爲http URL並指定一個方案),否則創建CFString或NSString,如果你使用CFURL或NSURL而沒有方案,很可能你會得到一個零。 – morph85 2013-06-30 11:39:34