我有一個作爲服務器運行的.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()
之後立即在我的服務器代碼中放置了一個斷點,但它從來沒有命中。似乎流打開,但套接字永遠不會連接?
你沒有指出,但你是否一步一步來看看你是否真的寫了任何東西到插座?如果你沒有,那麼你的bufferLength變量變成-1。然後這將會持續循環(因爲byteIndex永遠不會超過長度!在某些時候,你的(長度 - 字節索引)將小於1,並且這是我懷疑事情正在扔餅乾的地方。 – 2012-04-20 14:06:46
幫助網絡應用程序的另一件事是運行一個數據包嗅探器(wireshark甚至CocoaPacketAnalyzer)幫助非常大,然後你不必猜測爲什麼事情不起作用。 – 2012-04-20 14:08:54