Documentation Archive :搜xx编程指南,缺点就是苹果已经不再更新了。eg:CFNetwork Programming Guide、Stream Programming Guide。
documentation-Technologies :苹果目前维护更新的官方文档地址,可以用来搜API说明。缺点:都是一些API的介绍说明,原理性、系统性的东西很少。
Documentation Archive :搜xx编程指南,缺点就是苹果已经不再更新了。eg:CFNetwork Programming Guide、Stream Programming Guide。
documentation-Technologies :苹果目前维护更新的官方文档地址,可以用来搜API说明。缺点:都是一些API的介绍说明,原理性、系统性的东西很少。
传输控制协议(Transmission Control Protocol,TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP协议位于四层模型中的传输层
源端口:16bit,共65536个端口,端口0有特殊含义,不能使用,这样可用端口最多只有65535。
目的端口:16bit,接收方的端口号。
序号:32bit,可靠传输服务的关键字段。序号(sequence number, seq)是报文段首字节的字节流编号,TCP把数据看成是有序的字节流,TCP会隐式地对数据流的每个字节进行编号。第一个包的编号由本地随机产生,到达2^32-1后会再回到0。客户端、服务器端有各自的seq序号。序号主要用来解决网络包乱序(reordering)问题。
确认号:32bit,可靠传输服务的关键字段。确认号(acknowledgment number,ack)是期望的对方的下一个序号。主要用来解决不丢包的问题。
网络模型常见的有7,4,5层模型。
IP协议位于四层模型中的网络层。
版本:IP协议的版本,占4bit,目前的IP协议版本号为4,下一代IP协议版本号为6。注意这里讨论的是IPv4的报文,IPv6的报文已经不长这个样了。
首部长度:IP报头的长度。固定部分的长度(20字节)和可变部分的长度之和。共占4位。最大为1111,即10进制的15,以32bits4字节为单位,代表IP报头的最大长度可以为15个32bits(4字节),也就是最长可为15*4=60字节,除去固定部分的长度20字节,可变部分的长度最大为40字节。
服务类型:Type Of Service。
总长度:IP报文的总长度。报头的长度和数据部分的长度之和。用16位二进制数表示,单位为8bits1字节,因此,IP报文的最大长度为65535字节。但由于MTU的限制,超过的话需要分片传输。所以就必须要有分片相关信息的字段,后面三个就是分片相关的字段。
代码:
1 | { |
总结:
传入的range必须满足:(range.location + range.length) <= string.length,否则会发生越界崩溃。
看以下代码:
1 | NSUInteger a = 100; |
打印:
1 | 2023-04-30 13:10:02.474708+0800 PodDemo[22390:3868894] 1 |
po 与 p:对象最好使用po,基础数据类型使用p。
swift则会溢出崩溃:swift直接写上面的代码编译都通不过,得拐个弯:
1 | func myoverflow() { |
swift确实是一门安全的语言。
在读了一些框架源码后,个人觉得应该从以下几个方面学习一个框架:
1.框架实现的功能
这个框架是用来干嘛的。
2.框架的工作流程
高屋建瓴的描述一下框架的工作流程。
3.简单的使用框架
做一个小demo。
4.框架使用的基础库
基于哪些系统框架或其他第三方库。
5.框架的设计
架构设计,设计模式,数据结构和算法,类的UML图。
6.框架的实现细节
语言的高级使用,多线程处理,复用,内存优化,CPU优化,边界情况处理等等。
7.框架的优缺点
在对框架达到一定的了解后,明白框架的最佳使用场景及局限性。
8.对框架的改进
尝试解决框架中存在的不足。
大致有下面五种IO模型:
阻塞IO模型,非阻塞IO模型,IO复用模型,信号驱动IO模型,异步IO模型。
读数据,发现没有数据,线程就一直等待直到有数据读取。
读数据,发现没有数据,线程不等待直接返回读错误码。由于不知道什么时候会有数据所以这种非阻塞IO模型需要调用方不断检查是否有数据。
fd默认是阻塞IO访问,可以使用fcntl函数设置为非阻塞IO:
1 | status = fcntl(socketFD, F_SETFL, O_NONBLOCK); |
对非阻塞IO模型的一种改进,因为非阻塞IO模型需要不断检查是否有数据可读。假如有100个fd要读,那么就需要100个线程各自在不断的检查是否有数据可读,这显然浪费了大量的CPU和内存。
ifconfig
全称:interfaces config,主要用于设置或显示网络设备信息的。
打印:
1 | lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 |
ifconfig打印的是所有网络设备的信息,并且名称是专有名词比如en0,一般来说如果电脑只连了WIFI那么en0代表的就是WIFI网卡信息,如果还插了网线那么en0代表的就是以太网网卡信息,en1代表的才是WIFI网卡信息。可以配合networksetup -listallhardwareports
查看。
networksetup -listallhardwareports
打印:
1 | Hardware Port: Ethernet |
networksetup -listallnetworkservices
打印:
runloop启动前必须先添加输入源或定时器源,否则runloop一启动就会退出。总之runloop需要有监听的事件,否则就会退出。
NSRunLoop提供了如下3种启动runloop的方法。当然NSRunLoop其实封装的是CFRunloop。
1 | - (void)run NS_SWIFT_UNAVAILABLE_FROM_ASYNC("run cannot be used from async contexts."); |
相同点:如果没有输入源或定时器源附加到runloop上,runloop会马上退出,并且方法也会立即退出。
run
它会让runloop置身在一个永久的循环当中.即使runloop因为处理完了某个输入源事件而退出,该方法又会让它重新运行.因此如果你想处理完某个事件后能够退出runloop,那么你就不能使用该方法了。runloop运行在default模式。
runUntilDate:
和run方法差不多只是多了个截止时间,截止时间到了runloop就会退出。runloop同样运行在default模式。
runMode:beforeDate:
可以指定runloop运行的模式以及一个截止时间。处理定时器源事件后不会退出runloop,但处理输入源事件后会退出runloop,因此需要外部重新驱动进入runloop。
根据官方文档,手动移除输入源或定时器源不能确保runloop会退出。最好的办法是使用runMode:beforeDate:方法启动runloop,设立标志位,给子线程发送消息perform selector。