IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux网络IPC sockets -> 正文阅读

[系统运维]Linux网络IPC sockets

Linux网络IPC sockets


?

一、主机字节序和网络字节序

字节序分为大端和小端。

  • 大端字节序:正序存储,一个整数的高位(23-31bit)存储在内存的低地址处,低位字节(0-7bit)储存在高地址。网络通讯通常使用大端字节序,也称为网络字节序。
  • 小端字节序:逆序存储,一个整数的高位(23-31bit)存储在内存的高地址处,低位字节(0-7bit)储存在低地址。PC大多采用小端字节序,也称为主机字节序。

判断自己的电脑是大端还是小端代码:

#include <stdio.h>

union {
    short value;
    char ch[2];
}test;

int main()
{
    test.value = 0x0102;

    if (test.ch[0] == 1 && test.ch[1] == 2)
        printf("本机是大端字节序\n");
    else if (test.ch[0] == 2 && test.ch[1] == 1)
        printf("本机是小端字节序\n");
    else
        printf("本机字节序未知\n");
}

?

n->网络,h->主机	

Linux提供两种字节序之间的转换函数:

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

?

二、socket 地址格式

1、通用socket地址

不同格式的地址可以传递给套接字函数,被转换为通用的sockaddr地址结构。

#include <bits/socket.h>
struct sockaddr {
	sa_family_t sa_family; /* address family */
	char sa_data[14];      /* variable-length address */
};
  • sa_family :协议族(地址族)
  • sa_data: 存放地址数据

在这里插入图片描述

sa_data只有14字节,不够用时用下面这个新的socket通用地址结构体:

#include <bits/socket.h> 
struct sockaddr_storage
{
    sa_family_t sa_family;          /* address family */
    unsigned long int __ss_align;	/* Force desired alignment.  */
    char __ss_padding[128 - sizeof(__ss_align)];
};

?

2、专用socket地址

通用地址显然不好用,端口和IP需要复杂的位操作。
Linux为各个协议族提供了专门的socket地址结构体。

2.1、UNIX本地域协议族

#include <sys/un.h>
struct sockaddr_un
{
    sa_family_t sa_family;  /* address family */
    char sun_path[108];		/* Path name.  */
};

?

2.2、TCP/IP协议族IPv4

#include <netinet/in.h>
struct in_addr {
    in_addr_t s_addr;        /* IPv4 address, Network byte order */
};

struct sockaddr_in {
    sa_family_t sin_family;  /* address family */
    in_port_t sin_port;      /* port number */
    struct in_addr sin_addr; /* IPv4 address */
};

?

2.3、TCP/IP协议族IPv6

#include <netinet/in.h>
struct in6_addr {
    uint8_t s6_addr[16];       /* IPv6 address, Network byte order */
};

struct sockaddr_in6 {
    sa_family_t sin6_family;   /* address family */
    in_port_t sin6_port;       /* port number */
    uint32_t sin6_flowinfo;    /* traffic class and flow info */
    struct in6_addr sin6_addr; /* IPv6 address */
    uint32_t sin6_scope_id;    /* set of interfaces for scope */
};

?

3、IP地址转换

inet_addrinet_ntoa函数,用于在二进制地址格式和点分十进制(a.b.c.d)格式的字符串之间进行转换。这些函数仅适用于IPv4地址。

#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp); 
char *inet_ntoa(struct in_addr in);
in_addr_t inet_addr(const char *cp); // 等效inet_aton,但要谨慎使用,-1(255.255.255.255)时无效地址有问题。

要注意的是inet_ntoa是不可重入的,因为该函数内部用的是一个静态变量来储存转化结果,重复被赋值就不生效了,演示如下。

int main()
{
    struct in_addr addr1, addr2;

    inet_aton("1.2.3.4", &addr1);
    inet_aton("11.22.33.44", &addr2);

    char *sz_addr1 = inet_ntoa(addr1);
    char *sz_addr2 = inet_ntoa(addr2);

    printf("sz_addr1 = %s\n", sz_addr1);
    printf("sz_addr2 = %s\n", sz_addr2);
}
# 输出结果
sz_addr1 = 11.22.33.44
sz_addr2 = 11.22.33.44

?
新函数inet_ntopinet_pton支持类似的功能,并且可以同时使用IPv4和IPv6地址。

#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
int inet_pton(int af, const char *src, void *dst);

size指定目标存储单元的大小,下面两个宏分别用于IPv4和IPv6。

#include <netinet/in.h>
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46

?

三、创建socket

创建套接字,调用socket函数。

#include <sys/socket.h>
int socket(int domain, int type, int protocol);
// Returns: file (socket) descriptor if OK, ?1 on error
  • domain :域常用参数是AF_UNIX(AF_LOCAL)、AF_INET、AF_INET6。
  • type
SOCK_STREAM 流服务(常用于TCP)   
SOCK_DGRAM  传输使用UDP协议    
SOCK_RAW    数据报  
内核2.6.17之后,支持与运算下面的值
SOCK_NONBLOCK 创建的sokcet为非阻塞的   
SOCK_CLOEXEC  用fork创建子进程时在子进程中关闭该socket
  • protocol :在前两个参数的基础上指定一个具体的协议,通常为0。

?

四、服务端绑定socket地址

服务端必须将socket绑定到一个地址上,这个步骤也称为命名socket,客户端不需要绑定。
使用bind函数将地址与socket绑定起来。

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
// Returns: 0 if OK, ?1 on error

bind将addr所指向的socket地址分配给为命名的sockfd文件描述符,addrlen参数表示该socket地址的长度。
返回值常见的errno是EACCESEADDRINUSE

  • EACCES:被绑定的地址是受保护的地址,仅超级用户能访问,比如绑定到(0-1024)时。
  • EADDRINUSE:被绑定的地址正在使用中,比如绑定到一个处于TIME_WAIT状态的socket地址时。

?

五、服务端监听socket

socket绑定地址命名后,还不能接受客户端的链接,需要创建一个监听队列存放待处理的客户链接:

#include <sys/socket.h>
int listen(int sockfd, int backlog);
// Returns: 0 if OK, ?1 on error

backlog参数提示内核监听队列的最大长度。若监听队列的长度超过该值,服务器不再受理新客户的链接,客户端将受到ECONNREFUSED错误信息。

?

六、服务端接受连接

一旦服务器调用了listen,所使用的套接字就可以接收连接请求。 我们使用accept函数来检索连接请求并将其转换为连接。

#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict len);
// Returns: file (socket) descriptor if OK, ?1 on error

由accept返回的文件描述符是一个连接到调用connect的客户端的套接字描述符。 这个新的套接字描述符具有与原始套接字(sockfd)相同的套接字类型和地址族。 传递给accept的原始套接字与连接不相关,但仍然可用来接收其他连接请求。
如果不需要关心客户端的标识,可以将addr和len参数设置为NULL。 否则,在调用accept之前,需要将addr参数设置为一个足够大的缓冲区来保存地址,并将len所指向的整数设置为缓冲区的大小(以字节为单位)。 在返回时,accept将在缓冲区中填写客户端的地址,并更新len所指向的整数以反映地址的大小。

?

七、客户端发出连接

客户端使用connect函数来创建连接。

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t len);
// Returns: 0 if OK, ?1 on error
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:35:42  更:2022-03-21 21:39:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 0:33:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码