前言

说明:

  • demo 基于 Linux。

3. 地址族与数据序列

// 	调用 bind 函数分配IP地址和端口号。
// 成功时返回0,失败时返回-1
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen); /* 补充 client 部分 */
// 成功时返回0,失败时返回-1
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

3.1 分配给套接字的 IP 地址与端口号

参考: 李柱明博客园

3.2 参数 IP 地址

由于原生的参数 struct sockaddr 类型不够直观,所以采用类型转换的 struct sockaddr_in 只要保证其字节大小一样,然后把其当做一段微内存即可。

3.2.1 IPV4 地址的结构体

// 原生,不建议直接用
struct sockaddr {
sa_family_t sa_family; /* address family, AF_xxx */
char sa_data[14]; /* 14 bytes of protocol address */
}; // 格式转换后,推荐使用
struct sockaddr_in
{
sa_family_t sin_family; //地址族(Address Family)
uint16_t sin_port; //16 位 TCP/UDP 端口号
struct in_addr sin_addr; //32位 IP 地址
char sin_zero[8]; //为了保证其大小一致,目前不使用
}; struct in_addr
{
in_addr_t s_addr; //32位IPV4地址
}

3.2.2 地址族(Address Family)

成员 sa_family_t sin_family;

具体地址族类型参考 地址族(附件)

地址族(Address Family) 含义
AF_INET IPV4用的地址族
AF_INET6 IPV6用的地址族
AF_LOCAL 本地通信中采用的 Unix 协议的地址族

3.2.3 端口号

成员 uint16_t sin_port;

16 byte。

以网络字节序保存。(CPU 分大小端,为了统一,网络协同使用一种字节序来保证数据正确,到对端后再按需转换即可)

小知识

  • 可以这样区分 IP 和 端口号:一个主机可以共用一个 IP,端口号 用来区分主机程序。
  • 知名端口是要把该端口分配给特定的应用程序,范围是 0~1023 ,HTTP 的端口号是 80 ,FTP 的端口号是20和21。

3.2.4 IP 地址

成员 struct in_addr sin_addr;

32 byte。

以网络字节序保存。

小知识

  • 127.0.0.1 表示本机 IP。协议规定的。

3.2.5

成员 char sin_zero[8];

为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节,目前没有其它用途。

3.3 实例参考

注意:客户端创建socket后使用的函数是connect()。

#define cHOST "192.168.112.128" // 服务器端IP
#define cPORT 8080 // 服务器进程端口号 // 客户端
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET; // IPV4
serv_addr.sin_addr.s_addr = inet_addr(cHOST); // 地址
serv_addr.sin_port = htons(cPORT); //端口
//调用 connect 函数向服务器发送连接请求
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
error_handling("connect() error!");

3.4 网络字节序

3.4.1 字节序

得先了解大小端的问题。

本人的快速记忆是 小高高,意思是 字节放在位。

因为CPU有大小端的差异,如果不统一网络字节序就会导致数据交互错乱,如图:

网络字节序统一使用大端。

所以在收发前,先对数据进行检查、转换,再进行网络传输。

3.4.2 字节序转换相关函数

前后缀:

  • h:表示 host ,主机字节。
  • n:表示 network,网络字节。
  • s:表示 short。
  • l:表示 long。
unsigned short htons(unsigned short);
unsigned short ntohs(unsigned short);
unsigned long htonl(unsigned long);
unsigned long ntohl(unsigned long);

3.5 字符串转为网络字节序的整数形

3.5.1 inet_addr()

函数 inet_addr()

inet_addr是一个计算机函数,功能是将一个点分十进制的IP转换成一个长整数型数(u_long类型)等同于inet_addr()。

注意:一字节的范围为 [0:255]

// 返回:若字符串有效则将字符串转换为32位二进制网络字节序的IPV4地址,否则为INADDR_NONE
#include <arpa/inet.h> // Linux
in_addr_t inet_addr(const char* strptr); // 例子:
unsigned long conv_addrA = inet_addr("1.2.3.4"); // conv_addrA 为 0x4030201 unsigned long conv_addrB = inet_addr("1.2.3.256"); // conv_addr ERR,因为范围为 [0:255]

3.5.2 inet_aton()

函数 inet_aton()

函数 inet_aton() 和 函数 inet_addr() 在功能上是一样的,也是将字符串形式的IP地址转换成整数型的IP地址。

不同的是该函数得到的结果保存到 in_addr 结构体参数里面了,这样就可以判断有没有转换成功。

/*
string: 含有需要转换的IP地址信息的字符串地址值
addr: 将保存转换结果的 in_addr 结构体变量的地址值
成功时返回 1 ,失败时返回 0
*/
#include <arpa/inet.h>
int inet_aton(const char *string, struct in_addr *addr);

3.5.3 inet_ntoa()

函数 inet_ntoa()

该函数更好和 inet_aton() 相反,n -> a。

把网络字节整数型序转换为地址点分字符串形式。

特别注意

  • 该函数特点:其返回值为指针,实际内存实在函数里面申请的,该函数的实现里,只申请一次,下次调用时使用同样的已申请了的内存,(而不是重新申请,返回新的指针),所以下次调用该函数时,会把上次数据覆盖。
  • 使用注意:获取到返回的指针后,在下次调用该函数前,必须使用完毕或者把数据拷贝到新的内存里慢慢享受。
#include <arpa/inet.h>
char *inet_ntoa(struct in_addr adr);

3.6 网络地址初始化参考

struct sockaddr_in addr;
char *serv_ip = "192.168,1.2"; //声明IP地址族
char *serv_port = "8080"; //声明端口号字符串
memset(&addr, 0, sizeof(addr)); //结构体变量 addr 的所有成员初始化为0
addr.sin_family = AF_INET; //制定地址族
addr.sin_addr.s_addr = inet_addr(serv_ip); //基于字符串的IP地址初始化
addr.sin_port = htons(atoi(serv_port)); //基于字符串的IP地址端口号初始化

地址族(附件)

/* Supported address families. */
#define AF_UNSPEC 0
#define AF_UNIX 1 /* Unix domain sockets */
#define AF_LOCAL 1 /* POSIX name for AF_UNIX */
#define AF_INET 2 /* Internet IP Protocol */
#define AF_AX25 3 /* Amateur Radio AX.25 */
#define AF_IPX 4 /* Novell IPX */
#define AF_APPLETALK 5 /* AppleTalk DDP */
#define AF_NETROM 6 /* Amateur Radio NET/ROM */
#define AF_BRIDGE 7 /* Multiprotocol bridge */
#define AF_ATMPVC 8 /* ATM PVCs */
#define AF_X25 9 /* Reserved for X.25 project */
#define AF_INET6 10 /* IP version 6 */
#define AF_ROSE 11 /* Amateur Radio X.25 PLP */
#define AF_DECnet 12 /* Reserved for DECnet project */
#define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/
#define AF_SECURITY 14 /* Security callback pseudo AF */
#define AF_KEY 15 /* PF_KEY key management API */
#define AF_NETLINK 16
#define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */
#define AF_PACKET 17 /* Packet family */
#define AF_ASH 18 /* Ash */
#define AF_ECONET 19 /* Acorn Econet */
#define AF_ATMSVC 20 /* ATM SVCs */
#define AF_RDS 21 /* RDS sockets */
#define AF_SNA 22 /* Linux SNA Project (nutters!) */
#define AF_IRDA 23 /* IRDA sockets */
#define AF_PPPOX 24 /* PPPoX sockets */
#define AF_WANPIPE 25 /* Wanpipe API Sockets */
#define AF_LLC 26 /* Linux LLC */
#define AF_IB 27 /* Native InfiniBand address */
#define AF_MPLS 28 /* MPLS */
#define AF_CAN 29 /* Controller Area Network */
#define AF_TIPC 30 /* TIPC sockets */
#define AF_BLUETOOTH 31 /* Bluetooth sockets */
#define AF_IUCV 32 /* IUCV sockets */
#define AF_RXRPC 33 /* RxRPC sockets */
#define AF_ISDN 34 /* mISDN sockets */
#define AF_PHONET 35 /* Phonet sockets */
#define AF_IEEE802154 36 /* IEEE802154 sockets */
#define AF_CAIF 37 /* CAIF sockets */
#define AF_ALG 38 /* Algorithm sockets */
#define AF_NFC 39 /* NFC sockets */
#define AF_VSOCK 40 /* vSockets */
#define AF_KCM 41 /* Kernel Connection Multiplexor*/
#define AF_QIPCRTR 42 /* Qualcomm IPC Router */
#define AF_SMC 43 /* smc sockets: reserve number for
* PF_SMC protocol family that
* reuses AF_INET address family
*/

参考:

【网络编程】TCPIP_3_地址族与数据序列的更多相关文章

  1. TCP/IP网络编程之地址族与数据序列

    分配IP地址和端口号 IP是Internet Protocol(网络协议)的简写,是为收发网络数据而分配给计算机的值.端口号并非赋予计算机的值,而是为区分程序中创建的套接字而分配给套接字的序号 网络地 ...

  2. C/C++网络编程3——地址族与数据序列

    C/C++网络编程2中介绍了套接字,这一节介绍给套接字分配ip和端口号.ip用于标识一台主机,端口号用于标识一个主机中的一个应用程序,端口号占16位,0到65535,其中0到1023是知名端口号. 表 ...

  3. 【TCP/IP网络编程】:03地址族与数据序列

    上一篇文章介绍了套接字的创建过程,这篇文章主要讨论分配给套接字的IP地址和端口号的相关知识. IP地址和端口号 IP(Internet Protocol,网络协议)地址是收发网络数据而分配给计算机的值 ...

  4. 网络编程 --- URLConnection --- 读取服务器的数据 --- java

    使用URLConnection类获取服务器的数据 抽象类URLConnection表示一个指向指定URL资源的活动连接,它是java协议处理器机制的一部分. URL对象的openConnection( ...

  5. Linux网络编程-----Socket地址API

    (1) 通用socket地址 socket网络编程接口中表示socket地址的是结构体sockaddr,其定义如下: #include<bits/socket.h> struct sock ...

  6. Java网络编程:IP地址和端口号

    1)IP地址 用来标志网络中的一个通信实体的地址.通信实体可以是计算机,路由器等. 2)IP地址分类 IPV4:32位地址,以点分十进制表示,如192.168.0.1 IPV6:128位(16个字节) ...

  7. 网络编程--使用UDP发送接收数据

    package com.zhangxueliang.udp; import java.io.IOException; import java.net.DatagramPacket; import ja ...

  8. java网络编程_IP地址

    InetAddress类,此类表示Internet协议(IP)地址.具体使用方法查看文档:https://docs.oracle.com/en/java/javase/11/docs/api/java ...

  9. 网络编程 - 端口 & 地址占用

    1.设置地址复用(还可以设置端口复用): int enable=1; if (setsockopt(socketfd,SOL_SOCKET,SO_REUSEADDR,&iEnable,size ...

随机推荐

  1. Nginx 实践:location 路径匹配

    1. 目标 nginx 反向代理,路径映射的过程是什么?如何配置路径映射规则? 2.location 路径匹配 2.1 匹配规则: location 路径正则匹配: 符号 说明 ~ 正则匹配,区分大小 ...

  2. Linux创建ftp并设置权限以及忘记ftp帐号(密码)修改 (转)

      忘记ftp密码修改方法:1.登录服务器 cd  /etc/vsftpdcat ftpusers找到对应的ftp用户名 (如果用户名也忘记了 那么 cd /etc 然后cat passwd 查看用户 ...

  3. Vue | 路由守卫面试常考

    前言 最近在整理基础,欢迎掘友们一起交流学习 结尾有彩蛋哦! Vue Router 路由守卫 导图目录 路由守卫分类 全局路由守卫 单个路由守卫 组件路由守卫 路由守卫执行的完整过程 路由守卫分类 全 ...

  4. ftp错误&&详解方案

    一.FTP错误代码列表150 文件状态良好,打开数据连接 200 命令成功 202 命令未实现 211 系统状态或系统帮助响应 212 目录状态 213 文件状态 214 帮助信息,信息仅对人类用户有 ...

  5. 深入理解Java多线程——ThreadLocal

    目录 定义 API 场景分析 场景实验,观察Spring框架在多线程场景的执行情况 10000此请求,单线程 10000次请求,线程数加到100 对c的访问加锁 把c设为ThreadLocal 收集多 ...

  6. Scala学习——面向对象

    Scala面向对象 三大特征:封装.继承.多态 1.类的定义和使用 package top.ruandb.scala.Course02 object Simple { def main(args: A ...

  7. MYSQL一个设备上的主从复制实现-windows

    只记录一次在一个设备上实现mysql主从复制的过程,很详细,建议收藏,用到的时候照着步骤做就可以,会记录所有需要注意到的细节和一些容易遇到的坑以及解决办法! 如果需要在同一台电脑(服务器)上实现mys ...

  8. 【贪心+排序】排队接水 luogu-1223

    题目描述 有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小. 分析 注意要开longlong AC代码 #include &l ...

  9. bootstrap与vue的区别是什么?(十七)

    Bootstrap Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML.CSS.JavaScript 开发的简洁.直观.强悍的前端开发框 ...

  10. 第一篇 -- Sprint Tool Suite配置和Hello World编写

    首先需要安装 1. Sprint Tool Suite(本次所用版本:spring-tool-suite-3.8.3.RELEASE-e4.6.2-win32-x86_64) 2. Tomcat(本次 ...