学习地址:
C语言中文网 - 实现迭代服务端和客户端
GNU - Closing a Socket

前面介绍的程序,不管Service 端还是 Client端,都有一个问题,就是处理完一个 accept 请求立即退出,没有太大的实际意义。能不能像Web 服务器那样一直接收Client 端的请求呢?能,使用 While 循环即可。

修改前面的代码,是我们的服务端可以不断响应 Client 端的请求。

升级版Socket Demo

1. socket缓冲区

在迭代服务端和客户端的核心,就是如何使用write() 和 read() 函数,接下来介绍数据是如何传递的。

write() 函数并不立即向网络中传输 Data,而是先将 Data 写入缓冲区中,再由 TCP 协议将数据从缓冲区发送到目标机器。一旦将 Data 写入缓冲区,函数就可以成功返回,不管 Data 有没有到达目标机器,也不管他们何时被发送到网络,这些都是 TCP 协议负责的事情。

TCP 协议独立于 write() 函数,Data 有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这要取决于网络情况、当前线程是否空闲等诸多因素,不由程序员控制。

read()函数也是如此,也从输入缓冲区中读取 Data,而不是直接从网络读取。

这些I/O 缓冲区特性可整理如下:

  • I/O 缓冲区在每个 TCP 套接字中单独存在;
  • I/O 缓冲区在创建套接字时自动生成;
  • 即使关闭套接字也会继续传送输出缓冲区中遗留的 Data;
  • 但是关闭套接字也将丢失输入缓冲区中的 Data。

输入/输出 缓冲区的默认大小可以通过getsockopt() 函数获取:

    unsigned optVal;socklen_t optLen = sizeof(int);getsockopt(serv_socket, SOL_SOCKET, SO_SNDBUF, (char*)&optVal, &optLen);printf("Buffer length: %d\n", optVal);// 结果:2^17Buffer length: 131072 

2. 阻塞模式

对于 TCP 套接字(默认情况下)。

当使用write() 函数发送数据时:

  • 首先会检查输出缓冲区,如果缓冲区的可用长度小于要发送的数据,那么write() 会阻塞(暂停执行),直到输出缓冲区中的 Data 被发送到目标机器,腾出足够的空间,才唤醒 write() 函数继续写入 Data。
  • 如果 TCP 协议正在向网络发送 Data,那么输出缓冲区会被锁定,不允许吸入,write() 也会被阻塞(暂停执行),知道数据发送完毕输出缓冲区解锁,才唤醒write() 函数继续写入 Data。
  • 如果要写入的 Data 大于缓冲区的最大长度,那么 Data 将分批写入。
  • 知道所有的数据被写入输出缓冲区, write() 才能返回。

当使用read() 函数读取数据时:

  • 首先会检查输入缓冲区,如果缓冲区中有数据,那么就会读取,否则函数会被阻塞,知道网络上数据来到。
  • 如果要读取的数据长度小于缓冲区的数据长度,那么就不能一次性将缓冲区中的数据独处,剩余数据将不断积压,直到read() 函数再次读取。
  • 直到读取完数据之后,read() 函数才会返回,否则一直被阻塞。

阻塞模式总结

以上就是TCP 套接字的阻塞模式。所谓阻塞,也就是上一步动作没有完成,下一步动作将被暂停,直到上一步动作完成之后才能继续,以保持同步性。


3. 使用域名获取IP 地址

包含: #include<netdb.h>

首先介绍netdb.h 中的网络数据库返回的结构:

struct hostent {char    *h_name;    /* official name of host */char    **h_aliases;    /* alias list */int h_addrtype; /* host address type */int h_length;   /* length of address */char    **h_addr_list;  /* list of addresses from name server */
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#define h_addr  h_addr_list[0]  /* address, for backward compatibility */
#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
};
  • h_name :官方域名。
  • h_aliases :别名,多个域名访问同一个主机。同一个IP地址可以绑定多个域名,因此除了当前域名还可以指定其他域名。
  • h_addrtype :gethostbyname() 不仅仅支持IPv4,还可以支持IPv6,可以通过此成员获取IP 地址族信息。
  • h_lenght :保存IP 地址的长度,IPv4长度为4 个字节,IPv6长度为16 个字节。
  • h_addr_list :重要成员。通过该成员以整数形式保存域名对应的IP 地址。对于用户较多的服务器,可能会分配多个IP 地址给同一个域名,利用多个服务器进行均衡负载。

struct hostent 结构体变量的组成如下图所示:

测试代码:

假设获取本机的IP 地址。步骤:1.通过gethostname()获取本机的域名;2.通过gethostbyname() 获取域名的IP 数据库信息。

(因为在iOS8.0以上真机测试,通过gethostbyname() 无法解析域名来获取IP 信息了,推荐使用getifaddrst来获取IP地址)

    struct hostent * struct_hLib; // 储存IP信息的结构体char ** p_h_addr_list;        // 获取IP信息中IP列表char str[32];                 // 获取IP列表中具体的IP地址char hostname[32];            // 储存域名gethostname(hostname, sizeof(hostname));      // 获取本地域名,存储到hostnamestruct_hLib = gethostbyname(hostname);        // 获取指定域名的IP信息,存储到struct_hLibp_h_addr_list = struct_hLib->h_addr_list;     // 通过struck_hLib 获取IP列表for (; *p_h_addr_list!=NULL; p_h_addr_list++){//*> 打印具体的IP地址printf("address: %s\n",inet_ntop(struct_hLib->h_addrtype, *p_h_addr_list, str, sizeof(str)));}

打印结果:

address: 192.168.1.3

讲解一下inet_ntopgethostnamegethostbyname的用法:

1.inet_ntop:

const char * inet_ntop(int af, const void restrict src, char restrict dst, socklen_t size);

官方文档解释:

     The function inet_ntop() converts an address *src from network format(usually a struct in_addr or some other binary form, in network byteorder) to presentation format (suitable for external display purposes).The size argument specifies the size, in bytes, of the buffer *dst.  Itreturns NULL if a system error occurs (in which case, errno will havebeen set), or it returns a pointer to the destination string.  This func-tion functiontion is presently valid for AF_INET and AF_INET6.
  • af : Address Family。
  • src : 来自于网络地址格式,例如*p_h_addr_list 这种二进制形式的地址。
  • dst :存放转化后的字符串指针。
  • size : 返回字节的大小。

返回把网络地址转换成本地地址。

2.gethostname

int gethostname(char * destinnationStr, size_t);

  • destinnationStr :存放本地域名的字符串指针。
  • size_t : 存放本地地址的长度。

返回当前本地域名

3.gethostbyname

struct hostent gethostbyname(const char );

转载于:https://www.cnblogs.com/R0SS/p/5517729.html

【网络基础编程】第三节 C/S相关推荐

  1. Linux应用程序设计之网络基础编程

    1.TCP/IP协议概述 1.1.OSI参考模型及TCP/IP参考模型 OSI协议参考模型是基于国际标准化组织(ISO)的建议发展起来的,从上到下工分为7层:应用层,表示层,会话层,传输层,网络层,数 ...

  2. HNU计网实验:实验二 网络基础编程实验(JAVA\Python3)

    说些什么 记得当时做实验的时候我是满心的卧槽的,因为实验一和实验二简直是天壤之别,我记得在验收前的那个下午,我依然在疯狂改代码. 众所周知,我是一个衷心于摸鱼的小菜鸡,所以我这个代码其实是我在别人代码 ...

  3. Python3 与 C# 网络编程之~ 网络基础篇

    最新版本查看:https://www.cnblogs.com/dotnetcrazy/p/9919202.html 入门篇 官方文档:https://docs.python.org/3/library ...

  4. 网络编程—网络基础概览、socket,TCP/UDP协议

    网络基础概览 socket概览 socket模块-TCP/UDP的实现 TCP/UDP总结 网络基础概览 osi七层协议各层主要的协议 # 物理层传输电信号1010101010 # 数据链路层,以太网 ...

  5. 菜鸟学习笔记:Java提升篇9(网络1——网络基础、Java网络编程)

    菜鸟学习笔记:Java提升篇9(网络1--网络基础.Java网络编程) 网络基础 什么是计算机网络 OS七层模型 Java网络编程 InetAddress InetSocketAddress URL类 ...

  6. 第三模块 面向对象网络并发编程 | day17 面向对象基础

    第三模块 面向对象&网络&并发编程 从今天开始,我们将进入系列课程第3个模块的的学习,此模块包含如下三大部分知识: 面向对象,Python中支持两种编程方式来写代码,分别是:函数式编程 ...

  7. 计算机智能编程任务赛,网络基础赛 | 智能编程任务赛比赛规则

    原标题:网络基础赛 | 智能编程任务赛比赛规则 一. 比赛目标 <新一代人工智能发展规划>中指出,"要支持开展形式多样的人工智能科普活动,全面提高全社会对人工智能的整体认知和应用 ...

  8. python 复习——网络编程(三)——网络基础、多线程、ftp任务铺垫

    一.网络基础 学习网络编程,了解一些网络基础的知识是必不可少的,下面学习一些基础的网络知识: 1.我们的电脑里有网卡,网卡里有mac地址: 2.我到某个地方插上网线,路由器或交换机中的DHCP服务为我 ...

  9. 网络编程_1(网络基础+跨主机传输)

    一.网络基础 知识点回顾: 同一主机间的进程通讯方式: 1.无名管道(亲缘关系间的通讯,固定的读端和写端) 2.有名管道(半双工(因为文件可见,可再次打开交换读端写端),非亲缘关系) 3.信号 4.共 ...

  10. web编程之网络基础

    web编程之网络基础 一.TCP.IP网络: TCP/IP是"Transmission Control Protocol/Internet Protocol"的简写,翻译成中文为传 ...

最新文章

  1. python函数使用易错点_大部分人都会忽略的Python易错点总结
  2. html页面怎样禁止复制粘贴,javascript中如何禁止复制粘贴?
  3. 35+非常棒的视差滚动(Parallax Scrolling)效果WordPress主题
  4. Orace 11g 监听 配置修改 说明
  5. 【算法设计】虎溪校园导游系统
  6. android京东加入购物车效果,京东360buy 手机项目的“加入购物车”动画效果研究...
  7. SQL Server 2000从入门到精通3
  8. 【百科】走近飞天:伏羲——资源调度服务
  9. 试题 15 枚举n-m之间的所有质数(质数)
  10. [转]20个优秀网站助你征服CSS
  11. 在MFC中通过opencv显示摄像头视频或者文件视频
  12. count(*),count(1)和count(字段)的区别
  13. 人工智能ai医学辅助系统_不同的人工智能(AI)技术彻底改变了医学领域(AIM)...
  14. c# 多线程 源码5
  15. [Bullet3]常见物体和初始化
  16. 计算机国内外SCI/EI收录期刊一览(参考)
  17. 谷歌翻译api_解救科研民工!史上最强大的翻译神器,助你日读10篇不是梦~~
  18. Linux路由器流量统计系统
  19. Python实现支持向量机(基于双月数据集)
  20. 在网页中在线查看文档(doc、docx 、xls 、xlsx、 pdf 、swf )

热门文章

  1. [转] SQL Server中各个系统表的作用
  2. 电子设计竞赛方案搜集
  3. matplotlib画图一行三个图
  4. 【Albert】一文轻松理解Albert
  5. 【主成分分析法】NLPer的断舍离(下篇)
  6. 【Reformer】图解Reformer:一种高效的Transformer
  7. 深度学习2.0-11.tensorflow的高阶操作之高阶op
  8. 文本生成解码策略笔记-常见解码策略
  9. Netty的并发编程实践3:CAS指令和原子类
  10. Storm 实战:构建大数据实时计算