阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

UNIX网络通信详解

18次阅读
没有评论

共计 2774 个字符,预计需要花费 7 分钟才能阅读完成。

导读 计算机与计算机之间要有统一的连接标准才能够进行通信,这个标准称之为互联网协议,而网络就是物理链接介质 + 互联网协议。按照功能不同,人们将互联网协议分为 osi 七层或 tcp/ip 五层或 tcp/ip 四层,今天我们一起来看看 unix 网络通信原理
一、网络协议

国际标准化组织 (ISO) 定义了网络协议的基本框架,被称为 OSI 模型。OSI 模型包括应用层、表示层、会话层、传输层、网络层、数据链路层及物理层。而 OSI 模型过于复杂至今没有得到实际的应用。

TCP/IP 协议模型将 OSI 的 7 层协议模型简化为 4 层,从而更有利于实现和使用。TCP/IP 协议模型包括应用层、传输层、网络层、网络接口层。

TCP/IP 协议与 OSI 模型的对应关系如下图:

UNIX 网络通信详解

二、套接字 socket

它是一种可以进行网络通信的内核对象,它有一个唯一的标识符,一般称它为 socket 描述符,跟文件描述符类似,也可以用 read/wrote/close 操作。

int socket(int domain, int type, int protocol);/*
功能:创建 socket 对象
domain:通信地址类型
AF_UNIX / AF_LOCAL:本地进程间通信
AF_INET:使用 ipv4 地址通信
AF_INET6:使用 ipv6 地址通信
type:SOCK_STREAM:数据流协议,TCP 面向连接的通信协议
优点:安全可靠,数据不丢失,但速度慢。一般常用于安全性较高的场景
SOCK_DGRAM:数据报协议,UDP 面向无连接的通信协议
优点:速度快,数据可能会丢失,安全性和可靠性于 TCP 相比不高
一般用于安全性要求不高,但对速度有要求的场景。protocol:特殊协议一般不使用,直接写 0*/
准备通信地址:基本通信地址
struct sockaddr
{
sa_family_t sa_family;
char sa_data[14];
}
本地通信地址
struct sockaddr_un
{
// 通信地址类型
sun_family_t sun_family;
// socket 文件的路径
char sun_path[100];
}
网络通信地址
struct sockaddr_in
{
// 通信地址类型
short int sin_family;
// 端口号
in_port_t sin_port;
//ip 地址
struct in_addr sin_addr;
}
准备好的通信地址通常要将其强制转换成基本通信地址才能传给函数使用。int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
// 功能:把 socket 对象与通信地址建立联系
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
// 功能:连接通信目标
//socketaddr: 目标地址
三、网络通信的数据存储方式

个人计算机系统数据的存储方式可能是大端,也可能是小端,网络通信时需要的是大端数据,必须把数据转换成大端。

uint32_t htonl(uint32_t hostlong);
// 功能:把 32 位的主机字节序转换成 32 位的网络字节序
uint16_t htons(uint16_t hostshort);
// 功能:把 16 位的主机字节序转换成 16 位的网络字节序
uint32_t ntohl(uint32_t netlong);
// 功能:把 32 为网络字节序转换成 32 位的主机字节序
uint16_t ntohs(uint16_t netshort);
// 功能:把 16 为网络字节序转换成 16 位的主机字节序
生成端口号
端口号就是一个 16 为的无符号整数
uint16_t htons(uint16_t hostshort);
生成 ip 地址
in_addr_t inet_addr(const char *cp);
// 功能:把点分十进制的字符串 ip 地址转换成 32 位的无符号整数
char *inet_ntoa(struct in_addr in);
// 功能:把 32 位的网络字节序的 ip 地址转换成点分十进制的字符串 ip 地址
四、网络通信(UDP)

进程 A:创建 socket 对象 -> 准备地址 -> 绑定 -> 接收数据和来时的地址 -> 原路返回数据 -> 关闭 socket
进程 B:创建 socket 对象 -> 准备地址 -> 向目标发送数据 -> 接收数据 -> 关闭 socket

当 socket 对象被全部关闭后,会在内核中停留一段时间(给一个重新连接的机会),如果再使用同样的 ip 地址和端口号时就会失败(延时关闭)

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
// 功能:接收数据并获取发送端的地址
//addrlen:是参数,要得到的 src_addr 的长度
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
// 功能:发送数据到指定的目标
五、网络通信(TCP)

面向连接的网络通信,在通信过程中时刻保持连接,这种通信方式类似与打电话,能保证安全可靠、数据不丢失,但与 UDP 相比传输速度略低。

进程 A:创建 socket-> 准备地址 -> 绑定 -> 监听(设置队列长度)-> 等待连接 -> 通信 -> 关闭。
进程 B;创建 socket-> 准备地址 -> 连接 -> 通信 -> 关闭

int listen(int sockfd, int backlog);
// 功能:设置 socket 对象最大的排队数量
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
// 功能:等待其他主机与当前 socket 建立连接关系。// 返回值:建立连接的描述符,此后通信都用此描述符
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
// 功能:连接通信目标
//socketaddr: 目标地址
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
// 功能:网络通信专用的数据接收
//flag: 0 阻塞
// 1 不阻塞
// 返回值:-1 时,说明连接断开,此时应该结束循环
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
// 功能:网络通信专用的数据发送
// 返回值:-1 时,说明连接断开,此时应该结束循环

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2025-02-07发表,共计2774字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中