套接字地址结构

套接字的地址结构可以在两个方向上传播:从进程到内核和从内核到进程。

IPV4套接字地址结构

  • sin_len是长度字段,有的平台上的套接字没有这个东西,因为有外置的sizeof运算符。不是posxi标准强制的字段
  • sin_family,sin_addr,sin_port是posxi标准规定必须有的字段,分别是协议簇,IP地址,端口号。
  • sin_zero可以理解为占位符吧,供以后使用。而且也以便统一大小,所有的套接字地址结构大小都至少是16字节


注:sa_family_t一般是8位无符号整数,也可以是16位无符号整数。

定义数据类型是为了统一不同主机的类型,比如x86和x64,两台机器之间网络通信,那么不能用什么int和double这样的东西,因为这个东西在不同的机器上占用的空间可能是不一样的,而上述这些类型,确保在所有机器上都是一样的。套接字地址结构仅在给定主机上使用:虽然结构中的某些字段用在不同主机之间的通信中,但是结构本身并不在主机之间传递。

IPv 4地址和tcp或udp端口号在套接字地址结构中总是以网络字节序来存储。

通用的套接字地址结构


一般各种函数的参数都是通用套接字地址结构,而主机上使用的是固定的套接字地址结构,比如上面说的IPV4的套接字地质结构struct sockaddr_in,在C语言里可以用void*进行类型转换,但是在C++里不可以。比如:

IPV6的套接字地址结构

  • IPV6的协议簇是AF_INET6,IPV4是AF_INET

新的通用套接字地址结构

在<netinet/in.h>中定义

学unix环境高级编程的时候,没见用过这个结构体。

不同套接字的地址结构的比较

值-结果参数

我们提到过,当往一个套接字函数传递一个套接字地址结构时,该结构总是以引用形式来传递,也就是说传递的是指向该结构的一个指针。该结构的长度也作为一个参数来传递,不过其传递方式取决于该结构的传递方向:是从进程到内核,还是从内核到进程。

(1)从进程到内核传递套接字地址结构的函数又3个:bind、connect、sendto;这些函数的一个参数是套接字地址结构体的指针,另一个参数是结构体的整数大小;代表入参:

传递地址和大小的原因是告诉内核,应该复制那快内存,复制多大的内存。

(2)从内核到进程传递套接字地址结构体的函数有4个:accept、recvfrom、getsockname、getpeername;结构体指针和结构体大小的指针,都代表出参。

字节排序函数

字节序:大小端:术语“小端”和“大端”表示多字节值的哪一端(小端或大端)存储在该值的起始地址.

这两种字节序没有标准,且都有系统实用,而且还允许一个系统两者切换,所以我们把某个给定系统所用的字节序成为主机字节序;但是网络协议需要网络字节序
举例来说,在每个TCP分节中都有16位的端口号和32位的IPv4地址。发送协议栈和接收协议栈必须就这些多字节字段各个字节的传送顺序达成一致。网际协议使用大端字节序来传送这些多字节整数。

主机字节序与网络字节序相互转换

字节操纵函数

操纵多字节字段的函数有两组,它们既不对数据作解释,也不假设数据是以空字符结束的C字符串。当处理套接字地址结构时,我们需要这些类型的函数,因为我们需要操纵诸如IP地址这样的字段,这些字段可能包含值为0的字节,却并不是C字符串。以空字符结尾的C字符串是由在<string.h>头文件中定义、名字以str(表示字符串)开头的函数处理的。

BSD标准:现今几乎所有的套接字函数都只有它们,因为参数比较少,所以比较好记:

ANSI C标准:C标准库函数:

memset把目标字节串指定数目的字节置为值c。memcpy类似bcopy,不过两个指针参数的顺序是相反的。当源字节串与目标字节串重叠时,bcopy能够正确处理,但是memcpy的操作结果却不可知。这种情形下必须改用ANSI C的memmove函数。
memcmp比较两个任意的字节串,若相同则返回0,否则返回一个非0值,是大于0还是小于0则取决于第一个不等的字节:如果ptr1所指字节串中的这个字节大于ptr2所指字节中的对应字节,那么大于0,否则小于0。我们的比较操作是在假设两个不等的字节均为无符号字符( unsigned char)的前提下完成的。

inet_aton、inet_addr、inet_ntoa函数

地址转换函数,它们在ASCII字符串(这是人们偏爱使用的格式)与网络字节序的二进制值(这是存放在套接字地址结构中的值)之间转换网际地址。

第一个函数inet_aton将strptr所指C字符串转换成一个32位的网络字节序二进制值,并通过指针addrptr来存储。若成功则返回1,否则返回0。

inet_addr已经被弃用。
inet_addr进行相同的转换,返回值为32位的网络字节序二进制值。该函数存在一个问题:所有22个可能的二进制值都是有效的IP地址(从0.0.0.0到255.255.255.255),但是当出错时该函数返回INADDR_NONE常值(通常是一个32位均为1的值)。这意味着点分十进制数串255.255.255.255(这是IPv4的有限广播地址,见20.2节)不能由该函数处理,因为它的二进制值被用来标识该函数失败。
inet_addr函数还存在一个潜在的问题:一些手册页面声明该函数出错时返回-1而不是工NADDR_NONE。这样在对该函数的返回值(一个无符号的值)和一个负常值(-1)进行比较时可能会发生问题,具体取决于C编译器。

inet_ntoa函数将一个32位的网络字节序二进制IPv4地址转换成相应的点分十进制数串。由该函数的返回值所指向的字符串驻留在静态内存中。这意味着该函数是不可重入的,这个概念我们将在11.18节中讨论。最后需要留意,该函数以一个结构而不是以指向该结构的一个指针作为其参数。
函数以结构为参数是罕见的,更常见的是以指向结构的指针为参数。

inet_pton、inet_ntop函数

ipv4和ipv6都适用,进行大整数与点分式之间的转换。
函数名中p和n分别代表表达(presentation)和数值(numeric)。地址的表达格式通常是ASCII字符串,数值格式则是存放到套接字地址结构中的二进制值。

len参数是目标存储单元的大小,以免该函数溢出其调用者的缓冲区。为有助于指定这个大小,在<netinet/in.h>头文件中有如下定义:

sock_ntop和相关函数

inet_ntop的一个基本问题是:它要求调用者传递一个指向某个二进制地址的指针,而该地址通常包含在一个套接字地址结构中,这就要求调用者必须知道这个结构的格式和地址族。

而sock_ntop就是把这两个合并,不用再区分IPV4和IPV6,不是标准函数。
这也是这本书比较恶心的地方,tmd教人还用自己写的接口,还不放出接口源代码。

readn、writen、readline函数

字节流套接字(例如TCP套接字)上的read和write函数所表现的行为不同于通常的文件IO。字节流套接字上调用read或write输入或输出的字节数可能比请求的数量少,然而这不是出错的状态。这个现象的原因在于内核中用于套接字的缓冲区可能已达到了极限。此时所需的是调用者再次调用read或write函数,以输入或输出剩余的字节。有些版本的Unix在往一个管道中写多于4096字节的数据时也会表现出这样的行为。这个现象在读一个字节流套接字时很常见,但是在写一个字节流套接字时只能在该套接字为非阻塞的前提下才出现。尽管如此,为预防万一,不让实现返回一个不足的字节计数值,我们总是改为调用writen函数来取代write函数。

注:readn和writen这两个函数是我们自己定义的,只是为了以后方便使用。它们并非任何标准的组成部分。
还是建议实用标准的io函数,read,write。

C/C++Unix网络编程-套接字编程简介相关推荐

  1. UNIX网络编程---套接字编程简介(三)

    UNIX网络编程---套接字编程简介 一.概述 从这里开始正式开始网络编程之旅,所有的函数都是基本的库函数.这些都是网络编程的基础.Come on!!!! 二.套接字地址结构 大多数套接字函数都需要一 ...

  2. 【网络】网络基础套接字编程详解

      目录 网络初识 1.网络协议初识 2.网络协议的分层: OSI分层模型--->网络理论模型: TCP/IOP五层模型--->工业中采用的网络模型 为什么要有网络分层? 3.网络数据的封 ...

  3. 网络编程套接字编程-代码实现-复习总结

    文章目录 一.客户库例程设计 背景知识 前言知识 addrinfo 结构体 getaddrinfo() freeaddrinfo() socket() connect() close() gai_st ...

  4. 【Linux】网络基础+UDP网络套接字编程

    只做自己喜欢做的事情,不被社会和时代裹挟着前进,是一件很奢侈的事. 文章目录 一. 网络基础 1.局域网和广域网 2.协议初识和网络协议分层(TCP/IP四层模型) 3.MAC地址和IP地址(子网掩码 ...

  5. python 图形化socket编程_Python黑帽编程2.8 套接字编程

    Python黑帽编程2.8 套接字编程 套接字编程在本系列教程中地位并不是很突出,但是我们观察网络应用,绝大多数都是基于Socket来做的,哪怕是绝大多数的木马程序也是如此.官方关于socket编程的 ...

  6. Python黑帽编程2.8 套接字编程

    Python黑帽编程2.8 套接字编程 套接字编程在本系列教程中地位并不是很突出,但是我们观察网络应用,绝大多数都是基于Socket来做的,哪怕是绝大多数的木马程序也是如此.官方关于socket编程的 ...

  7. TCP和UDP套接字编程

    一.Socket简单介绍 如果要在应用层调用传输层的服务,进行相关程序的设计,就要涉及到套接字编程.套接字也称之为Socket,本质上它就是利用传输层提供的一系列Api来进行网络应用程序的设计. 网络 ...

  8. java套接字编程_Java套接字编程:教程

    java套接字编程 本教程是Java套接字编程的简介,从一个简单的客户机-服务器示例开始,该示例演示了Java I / O的基本功能. 将向您介绍原始的java.io软件包和NIO,即Java 1.4 ...

  9. 《UNIX网络编程 卷1:套接字联网API》学习笔记——基本TCP套接字编程

    UNIX网络编程--基本TCP套接字编程 socket 函数 connect 函数 bind 函数 listen 函数 accept 函数 fork 和 exec 函数 并发服务器 close 函数 ...

最新文章

  1. Codeforces Round #180 (Div. 2) A. Snow Footprints 贪心
  2. javascript基本数据类型问题汇总
  3. Android之解决NestedScrollView嵌套RecyclerView部分手机返回到这个页面Recyclerview顶部,而不是页面NestedScrollView顶部
  4. 【剑指offer - C++/Java】13、调整数组顺序使奇数位于偶数前面
  5. 想尝试转前端,但不知道从何学起
  6. 华为matebook和linux版本区别,华为MateBook14Linux版本开箱评测 | 从来没有让我们失望!...
  7. gcc/g++/make/cmake/makefile/cmakelists的恩恩怨怨
  8. VSCode安装教程详细简单版
  9. (生物信息学)R语言与统计学入门(十)—— 多因素Cox回归分析
  10. Lvgl(V8.2)自定义字体实现多国语言切换功能
  11. git使用教程10-修改 config 配置用户名和邮箱
  12. 【自我解析】2020华为杯数学建模比赛C题
  13. STM32F103RCT6开发板的下载
  14. 视频播放器源码(WinForm)
  15. ubuntu18.04桌面卡住鼠标可以动 键盘失效
  16. Docker 开启 remoter api
  17. Illustrator CS5扭曲功能初学者必读(2)——宽度工具
  18. 笔记34-JavaScript高级笔记
  19. 三国群英传霸业之王服务器维护,20190723维护公告
  20. [Practical.Vim(2012.9)].Drew.Neil.Tip16学习摘要

热门文章

  1. 武器排序HDU3293:sort
  2. 【R学习进阶】R中的VECTOR是什么意思?
  3. 有种友谊不低于爱情,不叫暧昧,叫蓝颜
  4. 景观设计主题命名_景观设计名字主题_园林景观好听的名字
  5. 钉钉小程序生态5—钉钉群机器人消息通知和钉钉工作通知
  6. adobe reader linux rpm,centos6.5下安装adobereader
  7. opencv——几何变换_透视
  8. 关于vscode粘贴时如果圆括号内内容太长会自动换行的问题
  9. Spring Boot 2.x :通过 spring-boot-starter-hbase 集成 HBase...
  10. 学习笔记:JAVA大数运算(数组方法)