紧接上一篇:
IOS网络篇7之基于第三方CocoaAsyncSocket实现Socket通信(发送图片以及类似http头信息)
一般情况下CFSocket 和NSStream我们不会直接对它进行操作,如果我们用到了这两个部分,那么说明我们使用的已经非常底层了,在开发一些SDK或者修改第三方的框架的时候是需要掌握这些知识的。
服务器端的流程:
(1)创建一个Socket端点
socketid = socket(AF_INET,SOCK_STREAM,0);
ADC Home > Reference Library > Reference > Mac OS X > Mac OS X Man Pages
为socket通信创建一个可以使用的通信端点。AF_INET:指明使用何种通信协议,这里使用的是tcp。
SOCK_STREAM:指明socket通信使用的流。socketid-1 表明socket创建错误。正确返回socket参考接口描述。
(2)初始化socket的参数并且将创建的socket名字绑定在我们刚新建的socket上
memset(&addr,0,sizeof(addr));
addr.sin_len =sizeof(addr);
addr.sin_family =AF_INET;
addr.sin_port =0;
addr.sin_addr.s_addr =INADDR_ANY;
// 将所创建的socket的名字绑定在这个socket上(fd)
bind(fd, (conststructsockaddr *) &addr,sizeof(addr));
(3)开始监听socket// 开始监听socket 5表示挂起连接队列中的最大值,如果队列已满,这个时候client会收到ECONNREFUSED。
listen(fd,5);
(4)获取当前使用的socket的名字getsockname(fd, (structsockaddr *) &addr, &addrLen);
(5)获取一个可用的端口号// 获取一个可用的socket端口号
port =ntohs(addr.sin_port);
(6)利用本地参数创建一个CFSocketRef 并添加到Runloop中CFSocketCreateWithNative(
NULL,
fd,
kCFSocketAcceptCallBack,
AcceptCallback,
&context
);
[NSOutputStreamoutputStreamToFileAtPath:self.filePathappend:NO];
(8)建立Socket和NSStream的联系
CFStreamCreatePairWithSocket(NULL, fd, &readStream,NULL);
(__bridgeNSInputStream *) readStream;
注意这里的readStream 是CFReadStreamRef。我们还需要将这个类型转化为NSInputStream。(9)设置NSStream的各种属性,delegate,打开这个输入流。
[NSSInputstream setProperty:(id)kCFBooleanTrueforKey:(NSString*)kCFStreamPropertyShouldCloseNativeSocket];
NSSInputstream.delegate =self;
[NSSInputstreamscheduleInRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];
[NSSInputstreamopen];
(10)回调方法中接收数据
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
这里最重要的一个枚举是:NSStreamEventHasBytesAvailable
bytesRead = [NSInputStream read:buffermaxLength:sizeof(buffer)];
将NSInputStream 流中的数据存储到buffer中。返回读取数据的长度。最大可读maxLength。
[NSOutputStreamwrite:&buffer maxLength:sizeof(buffer)];
将buffer中的数据写入的NSOutputStream中,这里outputstream又关联在一个本地文件中,所以最终写入到本地文件中。
(11)图片展示 :从本地文件中读取
image = [UIImageimageWithContentsOfFile:self.filePath];
客户端流程:这里的输入输出流的作用刚好相反,就不一一描述,有一个地方要注意下:client 建立连接的方法
[[NSNetServicealloc]initWithDomain:@"local."type:@"xxx"name:@"yyy"];