iOS基础之网络编程问题集

前言

现阶段工作需要和网络编程打交道,用的是第三方的CocoaAsyncSocket,虽然github上有文档但感觉真的不是非常详细,很多情况还是有很多比较迷惑的地方。这篇文章将记录我在学习应用过程中的一些迷惑点,希望能给别人帮助的同时给予自己帮助

正文

issue No1. GCDAsyncSocketDelegate下的socketDidDisconnect
完整的方法- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(nullable NSError *)err
已掌握:

  1. 这个方法是GCDAsyncSocketDelegate代理下的,由这个代理自动掉用(什么时候调用)
  2. 如果不想触发这个代理方法,只需要设置self.delegate = nil 就行了
  3. 连着的socket断开,把wifi断了以后,会自动掉用这个代理方法
  4. 物理网络断开,客户端和服务器的socket是不知道断开的,需要作处理(不知道CocoaAsyncSocket怎么处理的)
  5. 物理网络断开,客户端和服务器的socket其实没有断开,需要close(4次挥手)才会断开双方socket
  6. 当网络断开,还是可以通过socket来向外写数据的动作(只不过这时候写不出去),当写不出去(使用socket
  7. 通信不成功)的时候会触发这个回调函数socketDidDisconnect

困难点

  1. 什么时候掉用这个代理方法?
    先看一下文档的解释

If you call the disconnect method, and the socket wasn’t already disconnected, then an invocation of this delegate method will be enqueued on the delegateQueue before the disconnect method returns.
Note: If the GCDAsyncSocket instance is deallocated while it is still connected, and the delegate is not also deallocated, then this method will be invoked, but the sock parameter will be nil. (It must necessarily be nil since it is no longer available.) This is a generally rare, but is possible if one writes code like this:
asyncSocket = nil; // I’m implicitly disconnecting the socket
In this case it may preferrable to nil the delegate beforehand, like this:
asyncSocket.delegate = nil; // Don’t invoke my delegate method asyncSocket = nil; // I’m implicitly disconnecting the socket
Of course, this depends on how your state machine is configured.

如果你调用了disconnect方法,并且这个socket还没有断开,那么在disconnect方法返回之前会将这个代理方法(socketDidDisconnect)放到delegateQueue队列中。


ignore: disconnect会将这个代理方法放到队列中,等断开完毕的时候触发。看这个网络库很多都是放到队列里面的,比如writeData放到队列里面,readDataToLength放到队列里面,到后面满足某个情况触发


当这个socket还连接的时候,如果这个GCDAsyncSocket实例对象释放了,并且这个socket的delegate还没释放,那么这个方法会执行(在socket还连接的时候,我将socket=nil;释放对象,那么socket都释放了,socket.delegate 为什么还没释放,从而触发这个方法?),但是这个方法参数中的socket值是nil(它必须是nil,如果不再有效)。这是比较罕见的,但是它是有可能的,比如有人写成下面的代码
asyncSocket = nil; // I’m implicitly disconnecting the socket
这种情况它可能更喜欢事先将这个delegate设置为nil,像下面一样
asyncSocket.delegate = nil; //执行条件满足的情况下,也不要去执行我的代理方法。 asyncSocket = nil; //我暗中断开这个socket
当然,这是依靠你当前情况的电脑配置是怎么样的


ignore: 连接还在,代理还在,将socke实例对象释放了,这个方法将会掉用。我很想知道wifi关闭以后为什么会掉用这个代理方法


issue No.2 wifi断开以后,客户端和服务器的socket是否已断开
已掌握

  1. 客户端有一个socket用来和服务器通信,服务器也有一个soket和该客户端通信(客户端socket连接服务器时产生)
  2. 我重新连上网,是否可以继续通信
  3. 心跳包发送消息给服务器,让服务器明白这个socket还是有效的,当在一定时间内没收到心跳包消息,就将socket给断了

issue No.3 客户端同一个socket,有两个地方不停断发数据,那么在本机接收数据是如何的

已掌握

  1. 长连接接收数据,它的数据都是放到栈里面的(放到buffer里面的,服务器回应的数据是放一起的),可以通过readDataToLength去分隔开来,也可以如http协议一样适用\n来分隔
  2. 长连接是可靠的,有序的,会重发的,会避免堵塞的功能

问题点
1. 程序里面使用socket不断向服务器传送数据并显示进度条,另外一个地方需要用这个socket不断向服务器发送请求获取状态。 这样同一时间内socket在栈里面是什么样子的,如果接收的数据包是固定长度的,我依次读下来会不会读到两者结合的数据(A的head和B的body数据结合在一起了),我实际工作碰到的情况,两者向服务器发送的数据速度不一样,到时一方进度条停止(没有从栈里面读到属于进度条的数据,读到的都是状态的数据,所以进度条停止)。

未完待续

发布了88 篇原创文章 · 获赞 29 · 访问量 29万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章