提到网络编程,大家不得不提到一套网络编程的书**[TCP/IP网络协议]**三卷书,之前在工作的时,花了20块钱,买了一套盗版的.
看了前两卷,后一卷实在是太晦涩难懂了,就没看了,第三卷主要讲的是底层具体实现的原理.如果只是想了解下基本知识的,可以阅读下第一卷关于协议的讲解,这一卷讲的非常好,如果想研究的深入的话,可以再读读第二卷,第三卷.
如果真的想在网络编程研究的深入的话,这套书是必须看的,这本书由浅入深,知识点原理讲的都非常好.
那么今天就给大家来探究探究在iOS中socket编程是什么形式的?
在正式讲解之前,思考这样几个问题.
1.什么是socket编程?
2.socket的分类有哪些?
3.socket编程的流程是什么?
4.socket与HTTP有什么不一样的地方?
5.iOS使用的socket框架有哪些?
6.为什么要选择AsyncSocket?
7.CFSocket提供了哪些接口?
8.如何进行socket编程的?
9.AsyncSocket的优点?
10,AsyncSocket工作过程?
只有明白这些概念,才能更好的去理解socket运用的场景.现在我们对上面的问题进行一个一个来进行解释.
套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应 用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
如果对tcp的四层结构不了的,自己去百度查资料.
常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。
流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;
数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。
这里的流程我们要分为两个部分:
1) tcpSocket流程
2) UDPSocket流程
这两种他们的流程图是不一样.下面我们分别来看一下,他们的各自的流程图.
###1) tcpSocket流程
首先来看一下TCPSocke---客户—服务器程序设计基本框架
###2) UDPSocket流程
大家仔细看图有没有发现,不管是tcpSocket还是UDPSocket,都是三次握手,服务都是有8个函数,客户端5个函数.那么这些函数有什么用呢,下来来给大家介绍一下,这些函数.
####1)创建套接字
Socket(af,type,protocol)
####2)建立地址和套接字的联系
bind(sockid, local addr, addrlen)
####3)服务器端侦听客户端的请求
listen( Sockid ,quenlen)
####4)建立服务器/客户端的连接 (面向连接TCP)
客户端请求连接
Connect(sockid, destaddr, addrlen)
####5 服务器端等待从编号为Sockid的Socket上接收客户连接请求
newsockid=accept(Sockid,Clientaddr, paddrlen)
####6.发送/接收数据
面向连接:
send(sockid, buff, bufflen)
recv( )
####7.面向无连接:
sendto(sockid,buff,…,addrlen)
recvfrom( )
####8.释放套接字
close(sockid)
用到的函数大致就是这些,底层的C语言写法.
由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用 中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给 客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以 保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。
那么iOS中我们要进行socket编程,那么我们使用的框架是什么,系统有没有自带的socket API供我们使用?下面我们就来看看.
第一种: BSD Socket
BSD Socket 是UNIX系统中通用的网络接口,它不仅支持各种不同的网络类型,而且也是一种内部进程之间的通信机制。而iOS系统其实本质就是UNIX,所以可以用,但是比较复杂。
第二种:CFSocket
CFSocket是苹果提供给我们的使用Socket的方式,但是用起来还是会不太顺手。当然想使用的话,可以细细研究一下。今天我们主要来探讨CFSocket的具体使用
第三种:AsyncSocket
这种方式在开发项目中经常会用到的。
##6.为什么要选择CFSocket?
苹果官方自带的,方便.
我们用的框架是: CFSocket.那么客户端跟服务端,都有哪些API接口供我们使用呢?
##7.CFSocket服务器与客户端给我提供了哪些接口?
Server端:
用CFSocketCreate()创建socket;
再用CFSocketSetAddress()设置地址;
再用CFSocketCreateRunLoopSource()把socket添加到runloop;
在socket的回调方法中用 CFStreamCreatePairWithSocket()创建绑定到socket的
CFReadStreamReff流,再将CFReadStreamRef流转换成NSInputStream类型,设置好delegate,添加到runloop,最后open;
在- (void)stream:(NSStream*)aStream handleEvent:(NSStreamEvent)eventCode方法中处理NSStreamEventHasBytesAvailable事件读取流中的数据。
Client端:
用CFSocketCreate()创建socket;
再用CFSocketConnectToAddress()连接到指定地址;
再用CFSocketCreateRunLoopSource()把socket添加到runloop;
在socket的回调方法中用CFStreamCreatePairWithSocket()创建绑定到socket的
CFWriteStreamRef流,再将CFReadStreamRef流转换成NSInputStream类型,设置好delegate,添加到runloop,最后open;
在- (void)stream:(NSStream*)aStream handleEvent:(NSStreamEvent)eventCode方法中处理NSStreamEventHasSpaceAvailable事件向流中写数据。
##8.如何进行socket编程的?
这里请参考我的另外一篇博客:
地址:http://blog.csdn.net/baihuaxiu123/article/details/50810281
原代码也要,大家可以下载下来看一下.
##9.AsyncSocket的优点?
iphone的CFNetwork编程比较艰深。使用AsyncSocket开源库来开发相对较简单,帮助我们封装了很多东西。
我们用的框架是: AsyncSocket.那么客户端跟服务端,都有哪些API接口供我们使用呢?
##10,AsyncSocket工作过程?
###1) 建立连接
- (int)connectServer:(NSString *)hostIP port:(int)hostPort
###2) 连接成功后,会回调的函数
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
###3) 发送数据
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
###4) 接受数据
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
###5) 断开连接
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
- (void)onSocketDidDisconnect:(AsyncSocket *)sock
主要就是上述的几个方法,只是说在真正开发当中,很可能我们在收发数据的时候,我们收发的数据并不仅仅是一个字符串包装成NSData即可,我们很可能会发送结构体等类型,这个时候我们就需要和服务器端的人员协作来开发:定义怎样的结构体。
例子我就不去举例了,自己去写.