標籤:
基於ios 例子WiTap
1.建立本地的服務並設定監聽時間檢測是否有裝置串連。
NSNetService * server = [[NSNetService alloc] initWithDomain:@"local." type:kWiTapBonjourType name:@"Minwei" port:0];//[UIDevice currentDevice].nameif(self.server != nil) { [self.server setDelegate:self]; //self.server.includesPeerToPeer = YES; [self.server publishWithOptions:NSNetServiceListenForConnections]; [self.server scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSRunLoopCommonModes]; //[self.server publish];
}
2.建立本地的用戶端搜尋服務。
testServiceBrowser = [[NSNetServiceBrowser alloc] init];[testServiceBrowser setDelegate:self];//testServiceBrowser.includesPeerToPeer = YES;[testServiceBrowser searchForServicesOfType:kWiTapBonjourType inDomain:@"local"];
3當尋找到服務的時候會調用以下方法,尋找和移除來確定區域網路裡面有多少個IP串連上。
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didRemoveService:(NSNetService *)service moreComing:(BOOL)moreComing{ //[netService removeObject:service]; if(!moreComing){ NSLog(@"remove"); [netServices removeObject:service]; }}- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)service moreComing:(BOOL)moreComing{ // Only update the UI once we get the no-more-coming indication. //[netService addObject:service]; if(!moreComing){ NSLog(@"find"); [service setDelegate:self]; [netServices addObject:service]; //[service resolveWithTimeout:5.0]; }}
4.通過開啟NSInputStream和NSOutputStream來進行對第一個配對上的使用者進行串連
BOOL success;NSInputStream * inStream;NSOutputStream * outStream;success = [service getInputStream:&inStream outputStream:&outStream];if ( ! success ) { //進行重新串連} else { self.inputStream = inStream; self.outputStream = outStream; [self openStreams];}
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode{#pragma unused(stream) switch(eventCode) { case NSStreamEventOpenCompleted: { self.streamOpenCount += 1; assert(self.streamOpenCount <= 2); // Once both streams are open we hide the picker and the game is on. if (self.streamOpenCount == 2) { //串連成功 } } break; case NSStreamEventHasSpaceAvailable: { assert(stream == self.outputStream); // do nothing } break; case NSStreamEventHasBytesAvailable: {
//回調資訊成功 uint8_t b; NSInteger bytesRead; assert(stream == self.inputStream); bytesRead = [self.inputStream read:&b maxLength:sizeof(uint8_t)]; if (bytesRead <= 0) { // Do nothing; we‘ll handle EOF and error in the // NSStreamEventEndEncountered and NSStreamEventErrorOccurred case, // respectively. } else { if(b!=‘#‘){ passMessage[inum] = b; inum++; } else{ printf("%s", (char *)passMessage); NSString *result = [NSString stringWithCString:(char *)passMessage encoding:NSUTF8StringEncoding]; NSLog(@"%@", result); inum =0; } return; } } break; default: assert(NO); // fall through case NSStreamEventErrorOccurred: // fall through case NSStreamEventEndEncountered: {//重新查詢連結 } break; }}
附 openStreams ,closeStreams和發送資訊
- (void)openStreams{ assert(self.inputStream != nil); // streams must exist but aren‘t open assert(self.outputStream != nil); assert(self.streamOpenCount == 0); [self.inputStream setDelegate:self]; [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.inputStream open]; [self.outputStream setDelegate:self]; [self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.outputStream open];}- (void)closeStreams{ assert( (self.inputStream != nil) == (self.outputStream != nil) ); // should either have both or neither if (self.inputStream != nil) { [self.inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.inputStream close]; self.inputStream = nil; [self.outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.outputStream close]; self.outputStream = nil; } self.streamOpenCount = 0;}
send 方法
- (void)send:(uint8_t){ NSLog(@"send"); assert(self.streamOpenCount == 2); // Only write to the stream if it has space available, otherwise we might block. // In a real app you have to handle this case properly but in this sample code it‘s // OK to ignore it; if the stream stops transferring data the user is going to have // to tap a lot before we fill up our stream buffer (-: if ( [self.outputStream hasSpaceAvailable] ) { NSInteger bytesWritten; NSUInteger dataLength; NSUInteger soFar = 0; NSInteger written = 0; NSData * data = [@"qwertitiww#" dataUsingEncoding:NSUTF8StringEncoding]; const uint8_t * m = (Byte*)[data bytes]; dataLength = [data length]; do{ bytesWritten = [self.outputStream write:&m[soFar] maxLength:dataLength - soFar]; assert(bytesWritten!=0); if(written ==-1){ break; } else{ soFar += bytesWritten; } if (bytesWritten != dataLength) { [self setupForNewGame]; break; } }while (soFar != dataLength); }}
由於傳輸只能接受uint8_t所以需要傳送一個bytes來傳送字串 在最後#號是結束符來區分時候傳送完一個資訊
IOS 區域網路發送資訊