最近作了一個項目,支持Android和ios兩個平臺。 android
這個項目中會用到一些簡單的Socket通訊,因此就有機會接觸到了Android和ios兩個平臺的Socket實現。 ios
如今將android和ios的Socekt作一些總結: socket
Android: ide
//創建Socket鏈接 public boolean connect() throws IOException { LogUtils.LOGI(TAG, "Conect to socket in "); // Close socket first. close(); if (null == mControlSock) { try { mControlSock = PlainSocket.createPlainSocket(mRemoteAddr, SOCKET_PORT, LONG_TIMEOUT); setTimeout(); initStreams(); isCamMode = -1; // isConnected = true; } catch (IOException ex) { if (null != mControlSock) { mControlSock.close(); } mControlSock = null; // isConnected = false; // throw ex; ex.printStackTrace(); } } LogUtils.LOGI(TAG, "Conenect socket status = " + isConnected()); return isConnected(); } //斷開Socket鏈接 public void close() throws IOException { IOException ex = null; if (null != mWriter) { try { mWriter.close(); mWriter = null; } catch (IOException e) { ex = e; } } if (null != mReader) { try { mReader.close(); mReader = null; } catch (IOException e) { ex = e; } } if (null != mControlSock) { try { mControlSock.close(); mControlSock = null; } catch (IOException e) { ex = e; } } if (null != ex) { throw ex; } } //發送命令到Server端 public void writeCommand(String command) throws IOException { LogUtils.LOGI(TAG, "writeCommand ---> " + command); if (null == mWriter) { return; } try { mWriter.write(command + "\r\n"); mWriter.flush(); } catch (IOException ex) { throw new IOException(ex.getMessage()); } } //讀取Server端消息的線程 Runnable mReadSocketRunnable = new Runnable() { @Override public void run() { try { while (mCanReadSocekt) { // Thread.sleep(mReadInterval); String result = SocketClient.getInstance().readLine(); if (null == result || result.length() <= 1) continue; dispatchResponseFromDV(result); } } catch (Exception e) { e.printStackTrace(); } } };
IOS: oop
//調用此接口與socket鏈接 - (void)connect{ if (DV_CONNECTION_CONNECTED == _connectStatus) return; CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"10.10.1.1", 8150, &_readStream, &_writeStream); inputStream = (NSInputStream *)_readStream; // ivar [inputStream setDelegate:self]; [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [inputStream open]; outputStream = (NSOutputStream *)_writeStream; // ivar [outputStream setDelegate:self]; [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [outputStream open]; _connectStatus = DV_CONNECTION_CONNECTING; } //調用此接口與socket斷開鏈接 - (void)disConnect{ _connectStatus = DV_CONNECTION_DISCONNECTED; if (inputStream){ [inputStream close]; inputStream = nil; } if (outputStream){ [outputStream close]; outputStream = nil; } [self notifyDisConnected]; } //獲取socket的鏈接狀態 - (int)connectStatus{ return _connectStatus; } //註冊鏈接狀態的Delegate - (void)registerDVConnectionChangedDelegate:(id<DVConnectionChangedDelegate>)delegate { if (nil == _dvConnectionChangedDelegates || nil == delegate) return; if (DV_CONNECTION_CONNECTED == [self connectStatus]) [delegate onDVConnected]; else if (DV_CONNECTION_DISCONNECTED == [self connectStatus]) [delegate onDVDisConnected]; else if (DV_CONNECTION_CONNECT_FAILED == [self connectStatus]) [delegate onConnectedFailed]; [_dvConnectionChangedDelegates addObject:delegate]; } //反註冊鏈接狀態的Delegate - (void)unregisterDVConnectionChangedDelegate:(id<DVConnectionChangedDelegate>)delegate { if (nil == _dvConnectionChangedDelegates || nil == delegate) return; [_dvConnectionChangedDelegates removeObject:delegate]; } //發送命令給Server - (BOOL)sendCommand:(NSString *)string { while (true) { if ([outputStream hasSpaceAvailable]){ NSData *data = [[NSData alloc] initWithData:[string dataUsingEncoding:NSASCIIStringEncoding]]; [outputStream write:[data bytes] maxLength:[data length]]; NSLog(@"write command to dv: %@", string); return YES; } } return NO; } //Socket回調,能夠知道Socket的鏈接狀態,收到Server端發來的數據等 - (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { switch (streamEvent) { case NSStreamEventNone: [self notifyConnectedFailed]; NSLog(@"can not connect to socket"); break; case NSStreamEventOpenCompleted: if (theStream == inputStream) { [self notifyConnected]; } NSLog(@"Stream opened"); break; case NSStreamEventHasSpaceAvailable: { break; } case NSStreamEventHasBytesAvailable: if (theStream == inputStream) { uint8_t buffer[1024]; int len; while ([inputStream hasBytesAvailable]) { len = [inputStream read:buffer maxLength:sizeof(buffer)]; if (len > 0) { //一行做位一次會話傳給外邊解析 Iterator buff. uint8_t tmp_buffer[1024]; int tmp_buffer_start = 0; for (int i = 0; i < len; ++i) { if ('\n' == buffer[i]) { for (int j = tmp_buffer_start; j < i + 1; ++j) { tmp_buffer[j - tmp_buffer_start] = buffer[j]; } NSString *output = [[NSString alloc] initWithBytes:tmp_buffer length:(i - tmp_buffer_start + 1) encoding:NSASCIIStringEncoding]; if (nil != output) { [self notifyNewMessage:output]; NSLog(@"s: %@", output); } [output release]; memset(tmp_buffer, 0, sizeof(uint8_t) * 1024); tmp_buffer_start = i + 1; } } } } } break; case NSStreamEventErrorOccurred: NSLog(@"Can not connect to the host!"); // [self notifyConnectedFailed]; break; case NSStreamEventEndEncountered: NSLog(@"Closing stream..."); [theStream close]; [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [theStream release]; theStream = nil; break; default: NSLog(@"Unknown event"); } }