您的位置:首页 > 理论基础 > 计算机网络

Socket网络协议简单介绍和使用

2014-03-01 00:44 656 查看


Socket就是为网络服务提供的一种机制
在Unix中,网络既是Socket,并不局限在TCP/UDP ,Socket可以用于自定义协议,例如:QQ
通信的两端都是Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输
Socket通讯流程图:



socket通信的特点:使用Socket开发网络通讯

在Web服务(WebServices=>XML)大行其道的今天,调用Web服务的代价是高昂的,尤其是仅仅是抓取少量数据的时候尤其如此。
而使用Socket,可以只传送数据本身而不用进行XML封装,大大降低数据传输的开销(JSON)

Socket允许使用长连接,允许应用程序运行在异步模式(提高效率),只有在需要的时候才接收数据

iOS中常用的两种Socket类型

流式Socket(SOCK_STREAM):流式是一种面向连接的Socket,针对于面向连接的TCP服务应用
数据报式Socket(SOCK_DGRAM):数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用

简单步骤:

网络连接设置

设置网络连接,绑定到主机和端口
设置输入流和输出流的代理,监听数据流的状态

将输入输出流添加至运行循环
打开输入流和输出流

发送消息给服务器

有可读取字节时,读取服务器返回的内容

到达流末尾时,关闭流,同时并从主运行循环中删除

- (void)connectToServer:(NSString *)hostName port:(NSInteger)port
{
// 要进行Socket开发,以下代码都是固定的
// 设置网络
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;

// 此方法可以连接到服务器,并分配输入流和输出流的内存空间
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)hostName, port, &readStream, &writeStream);

// 记录已经分配的输入流和输出流
_inputStream = (__bridge NSInputStream *)readStream;
_outputStream = (__bridge NSOutputStream *)writeStream;

// 设置代理,监听输入流和输出流中的变化
_inputStream.delegate = self;
_outputStream.delegate = self;

// Scoket是建立的长连接,需要将输入输出流添加到主运行循环
// 如果不将流加入主运行循环,delegate拒绝工作
[_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[_outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

// 打开输入流和输出流,准备开始文件读写操作
[_inputStream open];
[_outputStream open];
}


#pragma mark NSStream的代理方法
/**
NSStreamEventNone = 0, // 无事件
NSStreamEventOpenCompleted = 1UL << 0, // 建立连接完成
NSStreamEventHasBytesAvailable = 1UL << 1, // 有可读的字节,接收到了数据,可以读了
NSStreamEventHasSpaceAvailable = 1UL << 2, // 可以使用输出流的空间,此时可以发送数据给服务器
NSStreamEventErrorOccurred = 1UL << 3, // 发生错误
NSStreamEventEndEncountered = 1UL << 4 // 流结束事件,在此事件中负责做销毁工作
*/
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{

switch (eventCode) {
case NSStreamEventOpenCompleted:
NSLog(@"连接完成");
break;
case NSStreamEventHasBytesAvailable:
NSLog(@"有可读字节");
// 读从服务器接收到得数据,从输入流中读取
// 先开辟一段缓冲区以读取数据,用空间来换取程序的简单
uint8_t buffer[1024];

// read返回的是输入流缓冲区中实际存储的字节数
NSInteger len = [_inputStream read:buffer maxLength:sizeof(buffer)];

if (len > 0) { // 读到数据
// 将buffer中的数据,转换成字符串,输出
NSString *str = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];

// 将接收到的内容添加到数组
[_dataList addObject:str];

// 刷新表格
[_tableView reloadData];
}

break;
case NSStreamEventHasSpaceAvailable:
NSLog(@"可以写入数据");
break;
case NSStreamEventErrorOccurred:
NSLog(@"发生错误");
break;
case NSStreamEventEndEncountered:
NSLog(@"流结束");
// 做善后工作
// 关闭流的同时,将流从主运行循环中删除
[aStream close];
[aStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
default:
break;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Socket 网络协议
相关文章推荐