如果把像钢筋水泥混凝土一样把泥土锁住中的所字换成手字好不好说明理由

中新经纬客户端1月17日电 (王永乐) 按照日程安排国家统计局今日(17日)将公布2019年中国经济“成绩单”,国内生产总值(GDP)增速是多少居民收入增速能否跑赢GDP?

剧透:GDP总量近100万亿元人均首超1万美元

2018年,中国GDP总量首次超过90万亿元修订值为91.93万亿元。

2019年前三季度中国GDP总量为697798亿元按可比价格计算,同比增长6.2%分季度看,一季度增长6.4%二季度增长6.2%,三季度增长6.0%

虽然2019年GDP具体数据尚待公布,但官方已有“剧透”:增速完成预期目标总量接近100万亿元,人均超过1万美元

国家发改委副主任宁吉喆今年1月11日表示,从总量上看2019年中国GDP预计接近一百万亿元,人均GDP预计将超过一万美元

宁吉喆同时表示,2019年经济运行始终保持在合理区间预计全年GDP增长能够实现年初预定的6%至6.5%的预期目标。

从机构预测的2019年中国GDP增速数据来看普遍不低於6.1%。

2019年12月9日中国社会科学院发布的《经济蓝皮书》认为,2019年中国经济运行总体平稳全年有望实现6.1%的增长,在全球主要经济体中表现较恏

2019年12月19日,世界银行发布了《中国经济简报》报告预测2019年中国经济增速为6.1%。报告认为中国经济在实际可支配收入强劲增长的支撑下仍保持相对韧性,较为宽松的政策应对缓解了部分外部因素影响

另据WIND数据,11家机构对2019年GDP增速的平均预测值为6.2%预测最大值为6.2%,最小值6.1%

凅定资产投资料平稳,投资潜力巨大

投资方面WIND数据显示,上海证券、西南证券等14家机构对2019年固定资产投资(不含农户)增速平均预测值为5.2%預测最大值为5.6%,最小值5.1%

国家统计局数据显示,2019年1—11月份全国固定资产投资(不含农户)533718 亿元,同比增长5.2%增速与1—10月份持平。从环比速度看11月份固定资产投资(不含农户)增长0.42%。

上海证券认为随着一系列“稳投资”政策的落地实施,全国固定资产投资增速稳步回升在补短板、新动能以及转型升级等方面的投资持续发力,投资结构继续优化投资对优化供给结构的关键性作用继续彰显。

民生证券在研报中指絀房地产受建安工程支撑仍有韧性,政策不松销售难有显著改善预计房地产投资小幅回落至10.0%。基建回暖补短板和稳投资政策利好接連不断释放,预计回升至3.8%

国家统计局新闻发言人付凌晖2019年12月16日表示,中国工业化、城镇化还没有完成未来投资潜力非常巨大。尽管基礎设施投资增速不是很高但潜力还是很大的,毕竟目前来看中国的人均基础设施投资存量与发达国家相比仍有较大差距新一代的基础設施像互联网、通信5G发展方面,空间也比较大;还有铁路、轨道交通、城市停车场等交通建设方面也有很大投资空间

机构:需求和价格端助力消费增长企稳

消费方面,WIND数据显示中信证券、海通证券等10家机构对2019年12月份社会消费品零售总额增速平均预测值为7.8%,预测最大值为8.3%最小值7.5%。

数据显示2019年11月份,社会消费品零售总额38094亿元同比名义增长8.0%;2019年1-11月份,社会消费品零售总额372872亿元同比增长8.0%。

民生证券在研報中指出12月商业活动受春节前置和经济预期改善可能有所提升,双十一需求透支可能拖累网上消费竣工加速回升带动房地产后周期消費回升,汽车零售难有显著改善复苏效果缓慢。

中信证券表示需求和价格端助力消费增长企稳。11月受到购物节的和物价抬升的影响洺义消费增速如期回升。12月受到春节提前以及部分节日的影响,预计消费需求端仍然有支撑

稳就业提前交卷,居民收入增速能否跑赢GDP

2019年前三季度,全国居民人均可支配收入22882元同比名义增长8.8%,扣除价格因素实际增长6.1%与经济增长基本同步。

与全国水平相比上海、北京、浙江、天津、江苏、广东、福建、山东、辽宁这9个省份的人均可支配收入超过全国平均线。其中上海、北京前三季度居民人均可支配收入突破5万元。

在前面的博文中我们讨论了进程間通讯(IPC)的各种常用手段但是那些手段都是指通讯双方在同一台机器上的情况。在现实生活中我们会经常接触到各种各样的网络应用程序比如大家经常使用的 ftp、svn、甚至QQ、迅雷等等,它们的通讯双方通常都是在不同的机器上的那么它们的通讯就是跨主机的进程间通讯叻,所以网络通讯也是一种进程间通讯的手段

跨主机的程序在传输数据之前要制定严谨的协议,不然对方可能会看不懂你发送的数据從而导致数据传送失败,甚至造成安全类bug所以跨主机的通讯就不像我们之前学习的在同一台主机上的进程间通讯那么简单了。

制定协议偠考虑的问题至少包括以下几点:

1)告诉对方自己的 IP 和端口;

先来看看 IP 和端口的概念

当我们的程序在进行网络通讯之前,需要先与自己嘚机器进行约定告诉操作系统我需要使用哪个端口,这样操作系统的某个端口在收到数据的时候就会发送给我们的进程当另一个程序吔来通知操作系统它要使用这个端口时,操作系统要保证这个端口只有我们使用而不能再让别人使用否则当它收到数据的时候就不知道應该发送给谁了。

当我们需要发送数据的时候也会使用这个端口进行发送,只有特殊情况才会使用别的端口或者使用多个端口

2)还要栲虑的问题是通信的双方应该采用什么数据类型呢?

假如通讯双方要传送一个 int 类型的数据那么对方机器上 int 类型的位数与我们机器上的位數是否相同呢?

也就是说 int 类型在我的机器上是 32bit但是在对方的机器上也是 32bit 吗?假设在对方机器上是 16bit那么我发送给它的 int 值它能正确解析吗?

所以通信双方的数据类型要采用完全一致的约定这个我们在下面会讨论如何让数据类型一致。

3)还要考虑字节序问题这个说的是大尛端的问题。

大端格式是:低地址存放高位数据高地址存放低位数据。

小端格式是:低地址存放低位数据高地址存放高位数据。

如图1 所示假设要存放的数据是 0x,那么 33 是低位30 是高位,在大端存储格式中30 存放在低位,33 存放在高位;而在小端存储格式中33 存放在低位,30 存放在高位

这个东西有什么作用呢?它其实就是我们使用的网络设备(计算机、平板电脑、智能手机等等)在内存当中存储数据的格式所以如果通讯双方的设备存储数据的格式不同,那么一端发送过去的数据另一端是无法正确解析的,这可怎么办呢

没关系,还好系統为我们准备了一组函数可以帮我们实现字节序转换我们可以像使用公式一样使用它们。

 

这组函数的名字好奇怪是吧所以为了便于记憶,在讨论它们的功能之前我们先来分析一下它们名字里的玄机:

这样一来就好理解多了吧它们的作用从名字中就可以看出来了,就是紦数据从主机序转换为网络序或者把数据从网络序转换为主机序。
网路字节序一般都是大端的而主机字节序则根据硬件平台的不同而鈈同(在 x86 平台和绝大多数的 ARM 平台都是小端)。所以为了简化我们编程的复杂度这些函数的内部会根据当前机器的结构自动为我们选择是否要转换数据的字节序。我们不用管到底我们自己的主机采用的是什么字节序只要是从主机发送数据到网络就需要调用 hton 函数,从网络接收数据到主机就需要调用 ntoh 函数
4)最后一项约定是结构体成员不对齐,由于数据对齐也是与硬件平台相关的所以不同的主机如果使用不哃的对齐方式,就会导致数据无法解析
如何使数据不对齐呢,只需要在定义结构体的时候在结尾添加 __attribute__((packed)) 就可以了见如下栗子:
 
网络传输嘚结构体中的成员都是紧凑的,所以不能地址对齐需要在结构体外面增加 __attribute__((packed))。
关于字节对齐的东西就足够写一篇博文了LZ 在这里仅仅简单介绍一下什么是字节对齐,如果感兴趣大家可以去查阅专门的资料
结构体的地址对齐是通过 起始地址 % sizeof(type) == 0 这个公式计算的,也就是说存放数據的起始地址位于数据类型本身长度的整倍数
如果当前成员的起始地址能被 sizeof 整除,就可以把数据存放在这;否则就得继续看下一个地址能不能被 sizeof 整除直到找到合适的地址为止。不适合作为起始地址的空间将被空(lang)闲(fei)


从进程间通信开始,我们写程序就是一步一步按部就班嘚写就可以了编写网络应用也一样,网络通信本质上就是一种跨主机的进程间通信(IPC)
在上一篇博文中我们了解了主动端和被动端的概念,那么接下来看看在 Socket 中主动端和被动端都要做什么

主动端(先发包的一方)

2.给 Socket 取得地址(可省略,不必与操作系统约定端口由操莋系统指定随机端口)

被动端(先收包的一方,先运行)

 
首先我们来看一个栗子看不懂没关系,稍后 LZ 会告诉大家用到的函数都是什么意思
proto.h 里面主要是通讯双方约定的协议,包含端口号、传送数据的结构体等等
 

rcver.c 是被动端的代码,也是通讯双方先启动的一端
 

snder.c 是主动端,主动向另一端发送消息这端可以不用向操作系统绑定端口,发送数据的时候由操作系统为我们分配可用的端口即可当然如果想要自己綁定特定的端口也是可以的。
 

由这三个文件组成的程序就可以进行网络通讯了不知道大家有没有注意到,无论是发送端还是接收端执荇的步骤都是固定的,将来大家在开发更复杂的网络应用时也是基于这几个步骤进行扩展
根据上面的代码中协议(proto.h)的定义,我们知道其中 msg_st 结构体中 name 成员的长度是固定的这样并不好用,那么我们就把它修改为变长结构体
修改成变长结构体很简单,只需把变长的部分放箌结构体的最后面然后通过 malloc(3) 动态内存管理来为它分配我们需要的大小。如下所示:
 
UDP 包常规的最大尺寸是 512 字节去掉包头的 8 个字节,再去掉结构体中除了最后一个成员以外其它成员大小的总和剩下的就是我们最后一个成员最大能分配的大小。
大家还记得如何操作一个文件嗎
1.首先通过 open(2) 函数打开文件,并获得文件描述符;

3.调用 close(2) 函数关闭文件释放相关资源。
没错在 Linux 的一切皆文件的设计理念中,网络也是文件网络之间的通讯也可以像操作文件一样,对它进行读写
在网络程序中,通常步骤是这样的:


3.调用 close(2) 函数关闭网络释放相关资源。你沒看错这个函数就是我们关闭文件描述符的时候使用的函数。
下面我们依次介绍上面遇到的各种函数
 
socket(2) 函数是用来获取对网络操作的文件描述符的,就像 open(2) 函数一样

  domain:协议族;
  type:链接方式;
  protocol:具体使用哪个协议。在 domain 的协议族中每一个对应的 type 都有一个或多个协議使用协议族中默认的协议可以填写 0。
返回值:如果成功返回的是一个代表当前网络链接的文件描述符,你要保存好它因为后续的網络操作都需要它。如果失败返回 -1,并设置 errno
下面就是 Linux 支持的协议族,也就是 domain 参数可以选择的宏它们都定义在 sys/socket.h 头文件中,所以想要使鼡下面的宏不要忘记包含这个头文件哟

AF_INET:IPV4 协议;这是我们最常见的协议族,通过 man 7 ip 可以得到有关这个协议族更详细的描述

AF_IPX:Novell 当年是网络嘚代名词,是非常古老的操作系统出现在 TCP/IP 之前;

AF_NETLINK:是用户态与内核态通信的协议;

AF_X25:这是很早的协议,感兴趣的话可以自己去 Google 一下;

AF_AX25:應用于业余无线电也称为短波通信,都是一些无线电爱好者使用的协议据说汶川地震时灾区所有通讯都瘫痪了,第一个求救信号就是短波发送出来的因为这些无线电爱好者家里一般都有大大小小的发电机。

AF_ATMPVC:当年如日中天后来死于封闭。协议设计得非常好后来几镓公司都为了拿大头就僵持起来,谁都没有推广它就在这时候以太网发展起来了,就把它打败了以太网发展起来就是因为很简陋,所鉯更容易推广

AF_APPLETALK:苹果使用的一个局域网协议;

AF_PACKET:底层 socket 所用到的协议,比如抓包器所遵循的协议一定要在网卡驱动层而不能在应用层,否则无法见到包封装的过程再比如 ping(1) 命令大家都熟悉吧,想要实现 ping(1) 命令就需要了解这个协议族感兴趣的话大家可以自行 Google 一下。

 
如果想要對网络编程进行更深入的学习那么《APUE》作者写的《UNIX 网络编程》有必要读一遍;《TCP/IP详解》三卷也要读一下,但是这三卷都很难读而且翻譯质量也一般,可以买一本中文的再找一本英文电子版的遇到中文的读不通的时候拿出来英文原文对照一下就可以了。

SOCK_STREAM:流式套接字特点是有序、可靠。有序、双工、基于链接的、以字节流为单位的

可靠不是指不丢包,而是流式套接字保证只要你能接收到这个包那麼包中的数据的完整性一定是正确的。

双工是指双方都能收发

基于链接的是指:比如大街上张三、李四进行对话,一定不会说每句话之湔都叫着对方的名字也就是说通信双方是知道对方是谁的。

字节流是指数据没有明显的界限一端数据可以分为任意多个包发送。

SOCK_DGRAM:报式套接字无链接的,固定的最大长度不可靠的消息。

就像写信无法保证你发出的信对方一定能收到,而且无法保证内容不会被篡改如果今天发了一封信,明天又发了一封信不能保证哪封信先到。大家都能收到这个包但是发现不是自己的之后就会丢弃,发现是自巳的包再处理有严格的数据分界线。更详细的解释可以参阅 man 手册

SOCK_SEQPACKET:提供有序、可靠、双向基于连接的数据报通信。

SOCK_RAW:原始的套接字提供的是网络协议层的访问。

SOCK_RDM:数据层的访问不保证传输顺序。

 

 

bind(2) 函数用于绑定本机端口就是提前跟操作系统约定好,来自 xx 端口的数据嘟要转交给我(当前进程)处理并且我占用了这个端口号别人(其它进程)就不能再使用了。

  sockfd:刚刚使用 socket(2) 函数得到的文件描述符表示要对该网络链接绑定端口。
  addr:要绑定到套接字上的地址根据不同的协议要在 man 手册第 7 章查阅具体的章节,然后在 Address Types 一栏里面找到对應的结构体比如你在调用 socket(2) 函数的时候,domain 参数选择的是 AF_INET那么这个结构体就可以在 man 手册 ip(7) 章节中找到。

以 AF_INET 为例下面这两个结构体就是在 ip(7) 中找到的。
 

大家可以看到这个结构体的类型是 struct sockaddr_in,而 bind(2) 函数的第二个参数 的类型是 struct sockaddr它们二者有什么关系呢?别瞎想不是继承关系啦,C 语言Φ没有继承这种东东在传参的时候直接把实参强转为 void* 类型即可,就像上面栗子中 rcver.c 写得那样

 


返回值是真正能接收到的字节数,返回 -1 表示夨败

为什么这么说呢,还记得上面我们提到过吗流式套接字是基于链接的,而报式套接字是无链接的那么我们再来观察下这两个函數的参数列表,很明显 recv(2) 函数并没有地址相关的参数而 recvfrom(2) 函数则会将对方的地址端口等信息回填给调用者。
网络中的数据只有单字节数据不鼡考虑字节序从网络上接收过来的数据只要涉及到字节序就需要使用 ntoh 系列函数进行字节序转换。这一组函数我们上面介绍过了没记住嘚童鞋可以往上翻。
 

 

这两个函数与 recv(2) 和 recvfrom(2) 函数正好是对应的它们的作用是向网络上发送数据。

  sockfd:通过哪个 Socket 往外发数据这个参数的值就昰在调用 socket(2) 函数的时候取得的;
  buf:要发送的数据;
  len:要发送的数据的长度;
  flags:特殊要求,没有填 0;
  src_addr:目标地址;就像上面峩们讨论 bind(2) 函数时一样具体使用哪个结构体要根据你在调用 socket(2) 函数的时候使用的具体协议族有关系,然后到对应的 man 手册第 7 章去查找
  addrlen:目标地址的长度;
返回值是真正发送出去的数据的长度;出现错误返回 -1 并设置 errno。
最后剩下 close(2) 函数就不需要 LZ 在这里介绍了吧如果还有童鞋对 close(2) 函数不熟悉,那么请翻阅到前面 文件 IO 部分的博文中复习一遍
上面我们讨论的是单点通讯,多点通讯只能用报式套接字来实现
一般多点通讯分为:广播 多播(组播)两种方式。

多播:都是 D 类地址以 224. 开头。224.0.0.1 是一个组播中的特殊地址发到这个地址的消息会强制所有组播哋址中的主机接收,类似于全网广播
注意:广播和组播仅在局域网内有效。

 

这两个函数用于读取和设置套接字的特殊要求




SO_BROADCAST:设置或获取广播标识,当这个标识被打开时才允许接收和发送报式套接字广播所以大家使用广播的时候不要忘记设置这个 opt,但在流式套接字中无效
 

下面来谈谈丢包和校验的问题。
UDP 会丢包为什么会丢包呢?因为不同的请求会选择不同的路径经过不同的路由器这些包到达路由器嘚时候会进入路由器的等待队列,当路由比较繁忙的时候队列就会满当队列满了的时候各个路由会根据不同的算法丢弃多余的包(一般昰丢弃新来的包或随机丢弃包)。所以丢包的根本原因是拥塞
ping 命令的 TTL 是一个数据包能够经过的路由器数量的上限,这个上限在 Linux 环境里默認是 64在 Windows 里默认是 128。假设从中国某个点发送一个包到美国的某个点从发出开始到中国的总路由器需要大约十几跳,从中国总路由到美国總路由大约两三跳就到了再从美国总路由到达目标点也经过大约十几跳,因此无论 TTL 是 64 还是 128 都足以从全球任何一个点发送数据到另一个点叻所以丢包绝不是因为 TTL 值太小导致的。
解决丢包的方法是使用流量控制之前我们写过令牌桶还记得吧?流控分为开环式和闭环式
我們在这里介绍一种停等式流控:它是一种闭环式流控。它的实现方式很简单一问一答即可。就是发送方每次发送一个数据包之后要等待接收方的响应确认接收方收到了自己的数据包后再发送下一个数据包。这种方式的特点是每次等待的时间是不确定的因为每次发包走嘚路径是不同的,所以包到达目的地的时间也是不同的而且还要受网络等环境因素影响。
并且停等式流控的缺点也很明显:
1.浪费时间哆数时间都花费在等待响应上面了。
2.双方发送包的数量增加了这也意味着丢包率升高了。
3.为了降低错误率实现的复杂度会变高。如果 s 端 data 包发过去了但是 c 端响应的 ack 包丢了,s 端过了一会儿没收到 ack 认为 data 丢了再次发送 data当 c 端再次收到一模一样的 data 包时不知道到底是有两段数据一模一样还是 s 端把包发重复了,所以需要给data包加编号这样 c 端就知道当前这个 data 包是合法的数据还是多余的数据了。
停等式流控虽然上升了丢包率但是能保证对方一定能收到数据包。
web 传输通常采用两种校验方案:
1.不做硬性校验:交给用户来做比如你在浏览网页,网页周边的廣告都加载出来了但是正文没有加载出来,你肯定会刷新页面吧但是如果正文加载出来了,周边的广告没有加载出来你会刷新网页┅定要让整个网页全部都加载完整再看内容码?
2.延迟应答:下次通讯的时候把上次的 ack 带过来表示上次的通讯是完整的。


不仅仅 data 包会出现延迟 ack 包也会出现延迟(见图3)。所以 ack 包也需要加编号为了防止被抓包,所以往往不会把原始的编号暴露出来比如将编号+1或-1再发送。
網络的拥塞不仅仅会带来丢包的问题还会带来延迟的问题。延迟并不可怕可怕的是延迟抖动。比如在北京看新闻联播和在云南看新闻聯播会是同时的吗肯定会有相应的延迟吧,每一帧都延迟就没关系就怕其中某些帧延迟,其它帧不延迟这样看到的内容就全乱了。
仩面说了用停等式流控可以保证数据一定能够让对方接收到但是有没有觉得速度慢了点?
可以通过窗口或滑动窗口提高速度见图4。


使鼡窗口协议的停等式流控不再是发送一个包之后等待 ack 然后再发送另一个包,而是一下子发送出去多个包(图中一次发送 5 个包)分别等待它们的响应后再发送下一批次的包。一次发送 5 个包那么窗口的大小就是 5。使用窗口协议就可以尽可能多的抢占公共资源(交换机的等待队列等)了这样传输效率相比简单的停等式流控就更高了。当然窗口的缺点也是显而易见的:窗口的大小不可变对于复杂的网络情況并不灵活。那么只要对窗口稍加改变就可以更灵活的应对复杂多变的网络环境:动态改变窗口的大小使之可以根据不同的网络情形动態的改变流控的速率,这样就可以平衡丢包率和传输速率之间的杠杆了这种可以动态调整窗口大小的协议叫做“滑动窗口”。关于窗口囷滑动窗口这里就不做过多介绍了感兴趣的童鞋可以去查阅一些专门的资料。
说完了 UDP接下来聊一聊 TCP。
说到 TCP 就不得不谈到 TCP 的三次握手見图 5。


TCP 都是要客户端先发起请求所以客户端可以称为“主动端”,而服务器被动接收请求所以服务端也可以称为“被动端”。往往服務端要先运行起来然后客户端再发送消息,否则客户端发送的包会因为找不到目的地而被丢弃
服务端收到客户端发来的 SYN 报文后,会响應 SYN+ACK 报文给客户端并将当前链接的一些信息放入一个叫做“半链接池”的缓冲区中,当超过一定时间后该客户端没有返回 ACK 报文服务端再紦这个半链接从半链接池中移除,释放相关资源
只要出现了“XX池”,那么该池的容量终归是有限的所以有一种下流的拒绝服务攻击手段就是利用大量的半链接把服务端的半链接池沾满,以实现拒绝服务攻击例如当很多肉鸡向某台服务器发送第一次握手(FIN)却永远不发送第三次握手(ACK),这样很快就把服务器的半链接池沾满了有效的用户也就无法请求服务器了,这就是下流的半链接攻击手段的大致原悝
防范半链接的手段就是取消半链接池,然后通过一个算法为每个链接计算出一个独一无二的标识再把这个标识放入 cookie 中通过 ACK 返回给客戶端。cookie 由内核产生仅保留这一秒和上一秒的 cookie。当用户再次请求时需要带着这个 cookie用相同的 cookie 计算,只要与用户带来的 cookie 相同就认为是合法用戶如果不相同就用上一秒的cookie再次计算和比较,如果还不相同就认为用户的cookie 是伪造的或是超时的,所以用户会立即重新建立第一次握手

其实在实践当中也会保留半链接池,里面仅仅存放频繁访问的用户来优化 cookie 方式的链接
简要的介绍了 TCP 的三次握手之后,我们来看看如何實现用 TCP 协议收发数据有关更详细的 TCP 知识,感兴趣的童鞋可以参阅《TCP/IP 卷一:协议》





4.接受链接 (accept(2)) 如果成功返回接受链接的文件描述符,失败返回 -1 并设置 errno注意不能直接用存放之前 socket(2) 返回的文件描述符变量来接收 accept(2) 的返回值,因为accept(2) 可能会遇到假错这样之前变量里保存的文件描述符僦丢了,会导致内存泄漏








proto.h,这个文件是客户端与服务端的协议双方共同遵守的格式要定义在这里,所以两边都要包含这个头文件
4 // 服務器端口号
 

server.c 服务端,要先运行起来监听指定的端口,操作系统指定的端口收到数据后就会送到服务端程序这里来
53 // 指定服务端使用的端ロ号
75 // 阻塞等待新消息传入
 

client.c 是客户端,也就是主动端它的发送端口可以不用手动指定而由操作系统来随机分配一个未被占用的端口。
32 // 指定垺务器的端口号
 

通过这几个栗子可以看出来TCP 一般使用 recv(3P)、send(3P) 等函数来收发数据,而 UDP 一般使用 recvfrom(3P)、sendto(3P) 等函数来收发数据因为 TCP 一开始就创建了稳定嘚链接,所以在通讯的过程中就不需要每次都指定对方的地址了而 UDP 是报式传输协议,并没有建立一个稳定的链接所以通讯的过程中要始终指定当前这个数据报要发送到哪里,或者是指明它是从哪里来的
最后再补充一点:如果 Ctrl+C 结束服务端,再次启动后执行 bind(2) 就会报错

使鼡 netstat -ant 命令会发现之前的链接都没有释放,且端口也没有释放所以由于无法监听一个没有被释放的端口就报错了。
有两种办法一种是等一會儿就好了,另一种是使用 setsockopt(2) 函数这个在上面 server.c 的注释中说明过了,没有注意到的童鞋请翻到上面去参考一下
为什么等一会儿就好了呢?洇为操作系统会经常检查有哪些端口被无效的进程占用了找到了就会释放这个端口。

Socket 的内容就先介绍到这里了其实它还有很多很多种鼡法,LZ 希望这篇文章能够起到抛砖引玉的作用感兴趣的童鞋可以通过《APUE》或者 man 手册学习到更多的用法。

我要回帖

更多关于 鹏程祛疤效果好吗 的文章

 

随机推荐