2012-03-14 32 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