最近做了一个项目,支持Android和ios两个平台。
这个项目中会用到一些简单的Socket通信,所以就有机会接触到了Android和ios两个平台的Socket实现。
现在将android和ios的Socekt做一些总结:
Android:
//建立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:
//调用此接口与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");
}
}