网站源码官网/济南做seo排名

网站源码官网,济南做seo排名,大连网站制作的公司哪家好,北京国税局网站做票种核定时1. 网络体系 1.1. 简介 网络采用分而治之的方法设计,将网络的功能划分为不同的模块,以分层的形式有机组合在一起。 每层实现不同的功能,其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务,同时使用下层提供…

1. 网络体系

1.1. 简介        

        网络采用分而治之的方法设计,将网络的功能划分为不同的模块,以分层的形式有机组合在一起。 每层实现不同的功能,其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务,同时使用下层提供的服务 网络体系结构即指网络的层次结构和每层所使用协议的集合 两类非常重要的体系结构:OSI与TCP/IP.

1.1.1. OSI开放系统互联模型

        OSI模型相关的协议已经很少使用,但模型本身非常通用 OSI模型是一个理想化的模型,尚未有完整的实现 OSI模型共有七层.

1.1.2. TCP/IP协议族的体系结构

        TCP/IP协议是Internet事实上的工业标准。 一共有四层

1.1.3. TCP协议通信模型

1.1.4. TCP/IP协议下的数据包

1.1.5. 数据的封装与传递过程

1.1.6. TCP/IP结构

1.1.7. TCP协议特点

        TCP(即传输控制协议):是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、数据无失序、数据无重复到达的通信) 适用情况: 适合于对传输质量要求较高,以及传输大量数据的通信。 在需要可靠数据传输的场合,通常使用TCP协议 MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议.

1.1.8. UDP协议特点

        UDP(User Datagram Protocol)用户数据报协议,是不可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。 适用情况: 发送小尺寸数据(如对DNS服务器进行IP地址查询时) 在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络) 适合于广播/组播式通信中。 MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议 流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输.

1.2. TCP/IP网络编程预备知识

1.2.1. Socket

        Socket 是一个编程接口 是一种特殊的文件描述符 (everything in Unix is a file) 并不仅限于TCP/IP协议 面向连接 (Transmission Control Protocol - TCP/IP) 无连接 (User Datagram Protocol -UDP 和 Inter-network Packet Exchange - IPX).

1.2.1.1.  Socket类型

        流式套接字(SOCK_STREAM) 提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。 数据报套接字(SOCK_DGRAM) 提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。 原始套接字(SOCK_RAW) 可以对较低层次协议如IP、ICMP直接访问.

1.2.1.2.  Socket的位置

1.2.2.  IP地址

        IP地址是Internet中主机的标识 Internet中的主机要与别的机器通信必须具有一个IP地址 IP地址为32位(IPv4)或者128位(IPv6) 每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由 表示形式:常用点分形式,如202.38.64.10,最后都会转换为一个32位的无符号整数。 IP地址分类 子网掩码.

1.2.3.  端口号

        为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号来区别 TCP端口号与UDP端口号独立 端口号一般由IANA (Internet Assigned Numbers Authority) 管理 众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用) 注册端口:1024~49150 动态或私有端口:49151~65535.

1.2.4. 字节序

        不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO): 小端序(little-endian) - 低序字节存储在低地址 将低字节存储在起始地址,称为“Little-Endian”字节序,Intel、AMD等采用的是这种方式; 大端序(big-endian)- 高序字节存储在低地址 将高字节存储在起始地址,称为“Big-Endian”字节序,由ARM、Motorola等所采用 网络中传输的数据必须按网络字节序,即大端字节序 在大部分PC机上,当应用进程将整数送入socket前,需要转化成网络字节序;当应用进程从socket取出整数后,要转化成小端字节序.

        网络字节序(NBO - Network Byte Order) 使用统一的字节顺序,避免兼容性问题 主机字节序(HBO - Host Byte Order) 不同的机器HBO是不一样的,这与CPU的设计有关 Motorola 68K系列、ARM系列,HBO与NBO是一致的 Intel X86系列,HBO与NBO不一致.

        大端(Big-Endian):字节的高位在内存中放在存储单元的起始位置.

 1.2.5. 字节序转换函数

        把给定系统所采用的字节序称为主机字节序。为了避免不同类别主机之间在数据交换时由于对于字节序的不同而导致的差错,引入了网络字节序。

        主机字节序到网络字节序:

                 u_long htonl (u_long hostlong);

                u_short htons (u_short short);

        网络字节序到主机字节序:

                 u_long ntohl (u_long hostlong);

                u_short ntohs (u_short short);

1.2.6. IP地址的转换

        inet_aton( )

                将strptr所指的字符串转换成32位的网络字节序二进制值

                #include <arpa/inet.h> int inet_aton(const char *strptr, struct in_addr *addrptr);         inet_addr( )

                功能同上,返回转换后的地址。

                int_addr_t inet_addr(const char *strptr);

        inet_ntoa( )

                将32位网络字节序二进制地址转换成点分十进制的字符串。

                char *inet_ntoa(stuct in_addr inaddr);

        inet_pton()

                将IPV4/IPV6的地址转换成binary格式     

                int inet_pton(int af, const char *src, void *dst);

2. 系统调用

2.1. 网络编程相关API

2.1.1. 网络编程常用函数

  • socket() 创建套接字
  • bind() 绑定本机地址和端口
  • connect() 建立连接
  • listen() 设置监听端口
  • accept() 接受TCP连接
  • recv(), read(), recvfrom() 数据接收
  • send(), write(), sendto() 数据发送
  • close(), shutdown() 关闭套接字

2.1.2. socket创建套接字

int socket(int domain, int type, int protocol);参数说明
domain (协议域):描述: 指定通信的协议域,即通信的地址族。
常见值:
AF_INET: IPv4协议族。
AF_INET6: IPv6协议族。
AF_UNIX 或 AF_LOCAL: 本地通信协议族,用于进程间通信(IPC)。
type (套接字类型):描述: 指定套接字的类型,即通信的语义。
常见值:
SOCK_STREAM: 提供面向连接的、可靠的、双向的、基于字节流的通信(如TCP)。
SOCK_DGRAM: 提供无连接的、不可靠的、基于数据报的通信(如UDP)。
SOCK_RAW: 提供原始网络协议访问。
SOCK_SEQPACKET: 提供面向连接的、可靠的、双向的、基于记录的通信。
protocol (协议):描述: 指定使用的具体协议。通常情况下,可以设置为0,表示使用默认协议。
常见值:
0: 使用默认协议。例如,对于AF_INET和SOCK_STREAM,默认协议是TCP;对于AF_INET和SOCK_DGRAM,默认协议是UDP。
具体协议值可以通过getprotobyname函数获取,但通常情况下设置为0即可。
返回值说明
成功:返回一个非负整数,表示新创建的套接字描述符(socket file descriptor)。
套接字描述符是一个整数,用于在后续的套接字操作中标识该套接字。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EAFNOSUPPORT: 指定的协议域不受支持。
EPROTONOSUPPORT: 指定的协议不受支持。
ESOCKTNOSUPPORT: 指定的套接字类型不受支持。
ENOBUFS 或 ENOMEM: 内存不足,无法创建套接字。

2.1.3. 地址相关的数据结构

通用地址结构struct sockaddr{    u_short  sa_family;    // 地址族, AF_xxxchar  sa_data[14];     // 14字节协议地址};Internet协议地址结构struct sockaddr_in{           u_short sin_family;      // 地址族, AF_INET,2 bytesu_short sin_port;      // 端口,2 bytesstruct in_addr sin_addr;  // IPV4地址,4 bytes 	char sin_zero[8];        // 8 bytes unused,作为填充}; 
IPv4地址结构
// internet address  
struct in_addr
{in_addr_t  s_addr;            // u32 network address 
};

2.1.4. bind绑定本机地址和端口

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数说明
sockfd (套接字描述符):描述: 表示要绑定的套接字的文件描述符。
类型: int
说明: 这个文件描述符通常是通过socket函数创建的。
addr (地址结构体指针):描述: 指向包含地址信息的struct sockaddr结构体的指针。
类型: const struct sockaddr *
说明: 这个结构体的具体类型取决于domain参数(例如,AF_INET使用struct sockaddr_in,AF_INET6使用struct sockaddr_in6)。
示例:
对于IPv4地址,通常使用struct sockaddr_in:struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = inet_addr("192.168.1.100");
对于IPv6地址,通常使用struct sockaddr_in6:struct sockaddr_in6 addr;
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(8888);
inet_pton(AF_INET6, "2001:db8::1", &addr.sin6_addr);
addrlen (地址结构体长度):描述: 指定addr参数指向的地址结构体的长度。
类型: socklen_t
说明: 这个参数通常通过sizeof运算符获取。
示例:
对于struct sockaddr_in:socklen_t addrlen = sizeof(struct sockaddr_in);
对于struct sockaddr_in6:socklen_t addrlen = sizeof(struct sockaddr_in6);
返回值说明
成功:返回0,表示绑定成功。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: sockfd不是一个有效的文件描述符。
ENOTSOCK: sockfd不是一个套接字。
EADDRINUSE: 指定的地址已经被其他套接字使用。
EADDRNOTAVAIL: 指定的地址不可用。
EFAULT: addr指向的内存区域不可访问。
EINVAL: addrlen不正确或addr指向的地址结构体不正确。
EACCES: 权限不足,无法绑定到指定的地址。

2.1.5. 地址结构的一般用法

// 定义并清空 sockaddr_in 类型的变量
memset(&myaddr, 0, sizeof(myaddr)); // 清空 myaddr 结构体// 填充地址信息
myaddr.sin_family = AF_INET; // 设置协议族为 IPv4
myaddr.sin_port = htons(8888); // 设置端口号,并转换为主机字节序到网络字节序
myaddr.sin_addr.s_addr = inet_addr("192.168.1.100"); // 设置服务器 IP 地址// 绑定套接字
if (bind(listenfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {perror("bind failed"); // 打印错误信息close(listenfd);       // 关闭套接字return -1;             // 返回错误码
}

2.1.6. 地址转换函数

unsigned long inet_addr(char *address);address是以’\0’结尾的点分IPv4字符串。该函数返回32位的地址。如果字符串包含的不是合法的IP地址,则函数返回-1。例如:
struct in_addr addr;
addr.s_addr = inet_addr(" 192.168.1.100 ");char* inet_ntoa(struct in_addr address);address是IPv4地址结构,函数返回一指向包含点分IP地址的静态存储区字符指针。如果错误则函数返回NULL

2.1.7. listen设置监听端口

int listen(int sockfd, int backlog);
参数说明
sockfd (套接字描述符):描述: 表示要监听的套接字的文件描述符。
类型: int
说明: 这个文件描述符通常是通过socket函数创建的,并且已经通过bind函数绑定到一个地址和端口。
backlog (最大连接队列长度):描述: 指定等待接受(accept)的连接队列的最大长度。
类型: int
说明:
backlog参数定义了内核为相应套接字排队的最大连接数。
当多个客户端同时尝试连接到服务器时,这些连接会被放入一个队列中等待处理。
如果队列已满,新的连接请求可能会被拒绝。
常见的backlog值为5、10或20,具体值可以根据实际需求调整。
返回值说明
成功:返回0,表示监听成功。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: sockfd不是一个有效的文件描述符。
ENOTSOCK: sockfd不是一个套接字。
EOPNOTSUPP: sockfd不支持监听操作。
EADDRINUSE: 地址已经被其他套接字使用。
EINVAL: sockfd已经处于监听状态,或者backlog参数无效。
EACCES: 权限不足,无法监听指定的地址。

        注意:完成listen()调用后,socket变成了监听socket(listening socket).

2.1.8. accept接受TCP连接

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数说明
sockfd (监听套接字描述符):描述: 表示要接受连接的监听套接字的文件描述符。
类型: int
说明: 这个文件描述符通常是通过socket函数创建的,并且已经通过bind函数绑定到一个地址和端口,然后通过listen函数设置为监听状态。
addr (客户端地址结构体指针):描述: 指向一个struct sockaddr类型的结构体,用于存储客户端的地址信息。
类型: struct sockaddr *
说明:
如果不需要客户端的地址信息,可以将此参数设置为NULL。
如果需要客户端的地址信息,需要先定义一个适当的结构体(如struct sockaddr_in),然后将其强制转换为struct sockaddr *类型。
例如,对于IPv4地址,可以使用struct sockaddr_in:struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_fd = accept(listenfd, (struct sockaddr *)&client_addr, &client_addr_len);
addrlen (地址结构体长度指针):描述: 指向一个socklen_t类型的变量,用于指定addr参数指向的地址结构体的长度。
类型: socklen_t *
说明:
在调用accept之前,需要初始化addrlen为地址结构体的实际大小。
例如,对于struct sockaddr_in,可以这样做:struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_fd = accept(listenfd, (struct sockaddr *)&client_addr, &client_addr_len);
在accept返回后,addrlen会被设置为实际存储的客户端地址信息的长度。
返回值说明
成功:返回一个新的套接字描述符,用于与客户端通信。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: sockfd不是一个有效的文件描述符。
ENOTSOCK: sockfd不是一个套接字。
EOPNOTSUPP: sockfd不支持接受操作。
ECONNABORTED: 连接被中断。
EINTR: 被信号中断。
EMFILE: 进程打开的文件描述符数量达到限制。
ENFILE: 系统打开的文件描述符数量达到限制。
ENOMEM: 内存不足,无法创建新的套接字。

2.1.9. connect 建立连接

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数说明
sockfd (套接字描述符):描述: 表示要连接的套接字的文件描述符。
类型: int
说明: 这个文件描述符通常是通过socket函数创建的,但尚未连接到任何远程地址。
addr (服务器地址结构体指针):描述: 指向一个struct sockaddr类型的结构体,用于存储服务器的地址信息。
类型: const struct sockaddr *
说明:
必须提供一个有效的服务器地址结构体,通常使用struct sockaddr_in(对于IPv4)或struct sockaddr_in6(对于IPv6)。
例如,对于IPv4地址,可以使用struct sockaddr_in:
c
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = inet_addr("192.168.1.100");
对于IPv6地址,可以使用struct sockaddr_in6:
c
struct sockaddr_in6 server_addr;
server_addr.sin6_family = AF_INET6;
server_addr.sin6_port = htons(8888);
inet_pton(AF_INET6, "2001:db8::1", &server_addr.sin6_addr);
addrlen (地址结构体长度):描述: 指定addr参数指向的地址结构体的长度。
类型: socklen_t
说明: 这个参数通常通过sizeof运算符获取。
示例:
对于struct sockaddr_in:socklen_t addrlen = sizeof(struct sockaddr_in);
对于struct sockaddr_in6:socklen_t addrlen = sizeof(struct sockaddr_in6);
返回值说明
成功:返回0,表示连接成功。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: sockfd不是一个有效的文件描述符。
ENOTSOCK: sockfd不是一个套接字。
EADDRINUSE: 本地地址已经被其他套接字使用。
EADDRNOTAVAIL: 本地地址不可用。
EAFNOSUPPORT: 地址族不支持。
EALREADY: 套接字是非阻塞的,并且连接操作正在进行中。
ECONNREFUSED: 连接被服务器拒绝。
EISCONN: 套接字已经连接。
ENETUNREACH: 网络不可达。
ETIMEDOUT: 连接超时。
EHOSTUNREACH: 主机不可达。
EINPROGRESS: 套接字是非阻塞的,并且连接操作正在进行中。
EINTR: 被信号中断。
EACCES: 权限不足,无法连接到指定的地址。

2.1.10. send数据发送

ssize_t send(int socket, const void *buffer, size_t length, int flags);
参数说明
socket (套接字描述符):描述: 表示要发送数据的套接字的文件描述符。
类型: int
说明: 这个文件描述符通常是通过socket函数创建的,并且已经通过connect函数连接到远程地址(对于TCP)或准备好发送数据(对于UDP)。
buffer (数据缓冲区):描述: 指向包含要发送数据的缓冲区的指针。
类型: const void *
说明:
buffer指向的数据可以是任意类型,但通常是一个字节数组。
使用const void *表示send函数不会修改缓冲区中的数据。
length (数据长度):描述: 指定要发送的数据长度(以字节为单位)。
类型: size_t
说明:
length参数指定buffer中要发送的字节数。
通常使用strlen函数获取字符串的长度,但要注意strlen不包括字符串结束符\0。
flags (标志位):描述: 指定发送操作的行为。
类型: int
说明:
flags参数可以是0,表示默认行为。
常见的标志位包括:
MSG_DONTROUTE: 不使用路由表查找目标地址。
MSG_OOB: 发送带外数据(仅适用于支持带外数据的协议,如TCP)。
MSG_NOSIGNAL: 如果发送操作导致对端关闭连接,不发送SIGPIPE信号。
MSG_CONFIRM: 确认连接(仅适用于某些协议)。
返回值说明
成功:返回实际发送的字节数(ssize_t类型)。
返回值可能小于length,表示部分数据已发送。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: socket不是一个有效的文件描述符。
ENOTSOCK: socket不是一个套接字。
EAGAIN 或 EWOULDBLOCK: 套接字是非阻塞的,并且当前不可写。
EDESTADDRREQ: 目标地址未指定(对于无连接的套接字,如UDP)。
EINTR: 发送操作被信号中断。
EINVAL: flags参数无效。
EISCONN: 套接字已经连接(对于无连接的套接字,如UDP)。
EMSGSIZE: 发送的数据长度超过协议允许的最大值。
ENOBUFS 或 ENOMEM: 内存不足,无法发送数据。
ENOTCONN: 套接字未连接(对于面向连接的套接字,如TCP)。
EPIPE: 对端关闭了连接(仅适用于面向连接的套接字,如TCP),并且flags未设置MSG_NOSIGNAL。

2.1.11. recv数据接收

ssize_t recv(int socket, void *buffer, size_t length, int flags);
参数说明
socket (套接字描述符):描述: 表示要接收数据的套接字的文件描述符。
类型: int
说明: 这个文件描述符通常是通过socket函数创建的,并且已经通过bind和listen函数设置为监听状态(对于TCP服务器),或者已经通过connect函数连接到远程地址(对于TCP客户端或UDP套接字)。
buffer (数据缓冲区):描述: 指向用于存储接收到的数据的缓冲区的指针。
类型: void *
说明:
buffer指向的数据可以是任意类型,但通常是一个字节数组。
recv函数会将接收到的数据存储在这个缓冲区中。
length (缓冲区长度):描述: 指定缓冲区的最大长度(以字节为单位),即最多可以接收的数据量。
类型: size_t
说明:
length参数指定buffer可以存储的最大字节数。
通常设置为缓冲区的实际大小减1,以确保有足够的空间存储字符串结束符\0(如果需要)。
flags (标志位):描述: 指定接收操作的行为。
类型: int
说明:
flags参数可以是0,表示默认行为。
常见的标志位包括:
MSG_DONTWAIT: 非阻塞模式,如果数据不可用,立即返回EAGAIN或EWOULDBLOCK。
MSG_OOB: 接收带外数据(仅适用于支持带外数据的协议,如TCP)。
MSG_PEEK: 查看数据而不从缓冲区中移除。
MSG_TRUNC: 返回实际接收的数据长度,即使数据被截断。
MSG_WAITALL: 等待直到接收指定数量的数据(仅适用于面向连接的套接字,如TCP)。
返回值说明
成功:返回实际接收的字节数(ssize_t类型)。
返回值可能小于length,表示部分数据已接收。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: socket不是一个有效的文件描述符。
ENOTSOCK: socket不是一个套接字。
EAGAIN 或 EWOULDBLOCK: 套接字是非阻塞的,并且当前没有数据可读。
EINTR: 接收操作被信号中断。
EINVAL: flags参数无效。
ENOMEM: 内存不足,无法接收数据。
ENOTCONN: 套接字未连接(对于面向连接的套接字,如TCP)。
EFAULT: buffer指向的内存区域不可访问。

2.1.12. read数据接收/write数据发送

        read()和write()经常会代替recv()和send(),通常情况下,看自己的的偏好使用read()/write()和recv()/send()时最好统一.

ssize_t read(int fd, void *buf, size_t count);
参数说明
fd (文件描述符):描述: 表示要读取数据的文件描述符。
类型: int
说明: 这个文件描述符可以是任何类型的文件描述符,包括套接字、文件、管道等。
buf (数据缓冲区):描述: 指向用于存储读取数据的缓冲区的指针。
类型: void *
说明:
buf指向的数据可以是任意类型,但通常是一个字节数组。
read函数会将读取的数据存储在这个缓冲区中。
count (数据长度):描述: 指定要读取的最大字节数。
类型: size_t
说明:
count参数指定buf可以存储的最大字节数。
实际读取的字节数可能小于count,具体取决于文件或套接字的状态。
返回值说明
成功:返回实际读取的字节数(ssize_t类型)。
返回值可能小于count,表示部分数据已读取。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: fd不是一个有效的文件描述符。
EAGAIN 或 EWOULDBLOCK: 文件描述符是非阻塞的,并且当前没有数据可读。
EINTR: 读取操作被信号中断。
EINVAL: buf指向的内存区域不可访问。
EIO: I/O 错误。
EFAULT: buf指向的内存区域不可访问。
EISDIR: fd是一个目录。
ECONNRESET: 连接被对端重置(仅适用于套接字)。
ssize_t write(int fd, const void *buf, size_t count);
参数说明
fd (文件描述符):描述: 表示要写入数据的文件描述符。
类型: int
说明: 这个文件描述符可以是任何类型的文件描述符,包括套接字、文件、管道等。
buf (数据缓冲区):描述: 指向包含要写入数据的缓冲区的指针。
类型: const void *
说明:
buf指向的数据可以是任意类型,但通常是一个字节数组。
write函数不会修改缓冲区中的数据。
count (数据长度):描述: 指定要写入的最大字节数。
类型: size_t
说明:
count参数指定buf中要写入的字节数。
实际写入的字节数可能小于count,具体取决于文件或套接字的状态。
返回值说明
成功:返回实际写入的字节数(ssize_t类型)。
返回值可能小于count,表示部分数据已写入。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: fd不是一个有效的文件描述符,或者不是打开用于写入的文件描述符。
EAGAIN 或 EWOULDBLOCK: 文件描述符是非阻塞的,并且当前不可写。
EINTR: 写入操作被信号中断。
EINVAL: buf指向的内存区域不可访问。
EIO: I/O 错误。
EFAULT: buf指向的内存区域不可访问。
ENOSPC: 设备上没有足够的空间写入数据。
EPIPE: 对端关闭了连接(仅适用于套接字),并且fd未设置O_NONBLOCK。
示例代码

2.1.13. sendto数据发送/recvfrom数据接收

        这两个函数一般在使用UDP协议时使用.

ssize_t sendto(int socket, const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
参数说明
socket (套接字描述符):描述: 表示要发送数据的套接字的文件描述符。
类型: int
说明: 这个文件描述符通常是通过socket函数创建的,并且可以是UDP套接字或未连接的TCP套接字。
message (数据缓冲区):描述: 指向包含要发送数据的缓冲区的指针。
类型: const void *
说明:
message指向的数据可以是任意类型,但通常是一个字节数组。
sendto函数不会修改缓冲区中的数据。
length (数据长度):描述: 指定要发送的数据长度(以字节为单位)。
类型: size_t
说明:
length参数指定message中要发送的字节数。
通常使用strlen函数获取字符串的长度,但要注意strlen不包括字符串结束符\0。
flags (标志位):描述: 指定发送操作的行为。
类型: int
说明:
flags参数可以是0,表示默认行为。
常见的标志位包括:
MSG_DONTROUTE: 不使用路由表查找目标地址。
MSG_OOB: 发送带外数据(仅适用于支持带外数据的协议,如TCP)。
MSG_NOSIGNAL: 如果发送操作导致对端关闭连接,不发送SIGPIPE信号。
MSG_CONFIRM: 确认连接(仅适用于某些协议)。
dest_addr (目标地址结构体指针):描述: 指向包含目标地址信息的struct sockaddr类型的结构体的指针。
类型: const struct sockaddr *
说明:
这个结构体的具体类型取决于socket的协议族(例如,AF_INET使用struct sockaddr_in,AF_INET6使用struct sockaddr_in6)。
例如,对于IPv4地址,通常使用struct sockaddr_in:struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(8888);
dest_addr.sin_addr.s_addr = inet_addr("192.168.1.100");
对于IPv6地址,通常使用struct sockaddr_in6:struct sockaddr_in6 dest_addr;
dest_addr.sin6_family = AF_INET6;
dest_addr.sin6_port = htons(8888);
inet_pton(AF_INET6, "2001:db8::1", &dest_addr.sin6_addr);
dest_len (目标地址结构体长度):描述: 指定dest_addr参数指向的地址结构体的长度。
类型: socklen_t
说明: 这个参数通常通过sizeof运算符获取。
示例:
对于struct sockaddr_in:socklen_t dest_len = sizeof(struct sockaddr_in);
对于struct sockaddr_in6:socklen_t dest_len = sizeof(struct sockaddr_in6);
返回值说明
成功:返回实际发送的字节数(ssize_t类型)。
返回值可能小于length,表示部分数据已发送。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: socket不是一个有效的文件描述符。
ENOTSOCK: socket不是一个套接字。
EAGAIN 或 EWOULDBLOCK: 套接字是非阻塞的,并且当前不可写。
EDESTADDRREQ: 目标地址未指定(对于无连接的套接字,如UDP)。
EINTR: 发送操作被信号中断。
EINVAL: flags参数无效。
EMSGSIZE: 发送的数据长度超过协议允许的最大值。
ENOBUFS 或 ENOMEM: 内存不足,无法发送数据。
ENOTCONN: 套接字未连接(对于面向连接的套接字,如TCP)。
EPIPE: 对端关闭了连接(仅适用于面向连接的套接字,如TCP),并且flags未设置MSG_NOSIGNAL。
ssize_t recvfrom(int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len);
参数说明
socket (套接字描述符):描述: 表示要接收数据的套接字的文件描述符。
类型: int
说明: 这个文件描述符通常是通过socket函数创建的,并且可以是UDP套接字或未连接的TCP套接字。
buffer (数据缓冲区):描述: 指向用于存储接收到的数据的缓冲区的指针。
类型: void *
说明:
buffer指向的数据可以是任意类型,但通常是一个字节数组。
recvfrom函数会将接收到的数据存储在这个缓冲区中。
length (缓冲区长度):描述: 指定缓冲区的最大长度(以字节为单位),即最多可以接收的数据量。
类型: size_t
说明:
length参数指定buffer可以存储的最大字节数。
通常设置为缓冲区的实际大小减1,以确保有足够的空间存储字符串结束符\0(如果需要)。
flags (标志位):描述: 指定接收操作的行为。
类型: int
说明:
flags参数可以是0,表示默认行为。
常见的标志位包括:
MSG_DONTWAIT: 非阻塞模式,如果数据不可用,立即返回EAGAIN或EWOULDBLOCK。
MSG_OOB: 接收带外数据(仅适用于支持带外数据的协议,如TCP)。
MSG_PEEK: 查看数据而不从缓冲区中移除。
MSG_TRUNC: 返回实际接收的数据长度,即使数据被截断。
MSG_WAITALL: 等待直到接收指定数量的数据(仅适用于面向连接的套接字,如TCP)。
address (源地址结构体指针):描述: 指向一个struct sockaddr类型的结构体,用于存储发送方的地址信息。
类型: struct sockaddr *
说明:
如果不需要发送方的地址信息,可以将此参数设置为NULL。
如果需要发送方的地址信息,需要先定义一个适当的结构体(如struct sockaddr_in),然后将其强制转换为struct sockaddr *类型。
例如,对于IPv4地址,可以使用struct sockaddr_in:struct sockaddr_in src_addr;
socklen_t src_addr_len = sizeof(src_addr);
ssize_t bytes_received = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&src_addr, &src_addr_len);
对于IPv6地址,可以使用struct sockaddr_in6:struct sockaddr_in6 src_addr;
socklen_t src_addr_len = sizeof(src_addr);
ssize_t bytes_received = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&src_addr, &src_addr_len);
address_len (源地址结构体长度指针):描述: 指向一个socklen_t类型的变量,用于指定address参数指向的地址结构体的长度。
类型: socklen_t *
说明:
在调用recvfrom之前,需要初始化address_len为地址结构体的实际大小。
例如,对于struct sockaddr_in,可以这样做:struct sockaddr_in src_addr;
socklen_t src_addr_len = sizeof(src_addr);
ssize_t bytes_received = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&src_addr, &src_addr_len);
在recvfrom返回后,address_len会被设置为实际存储的发送方地址信息的长度。
返回值说明
成功:返回实际接收的字节数(ssize_t类型)。
返回值可能小于length,表示部分数据已接收。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: socket不是一个有效的文件描述符。
ENOTSOCK: socket不是一个套接字。
EAGAIN 或 EWOULDBLOCK: 套接字是非阻塞的,并且当前没有数据可读。
EINTR: 接收操作被信号中断。
EINVAL: flags参数无效。
ENOMEM: 内存不足,无法接收数据。
ENOTCONN: 套接字未连接(对于面向连接的套接字,如TCP)。
EFAULT: buffer或address指向的内存区域不可访问。

2.1.14. close关闭套接字

        关闭双向通讯.

int close(int sockfd);
参数说明
sockfd (文件描述符):
描述: 表示要关闭的文件描述符。
类型: int
说明: 这个文件描述符可以是任何类型的文件描述符,包括套接字、文件、管道等。
返回值说明
成功:返回0,表示文件描述符关闭成功。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: sockfd不是一个有效的文件描述符。
EINTR: 关闭操作被信号中断。

2.1.15. shutdown关闭套接字

        TCP连接是双向的(是可读写的),当我们使用close时,会把读写通道都关闭,有时侯我们希望只关闭一个方向,这个时候我们可以使用shutdown。 针对不同的howto,系统回采取不同的关闭方式。

int shutdown(int sockfd, int howto);
参数说明
sockfd (套接字描述符):描述: 表示要关闭的套接字的文件描述符。
类型: int
说明: 这个文件描述符通常是通过socket函数创建的,并且已经通过bind和listen函数设置为监听状态(对于TCP服务器),或者已经通过connect函数连接到远程地址(对于TCP客户端或UDP套接字)。
howto (关闭方式):描述: 指定关闭套接字的方式。
类型: int
说明:
howto参数可以是以下值之一:
SHUT_RD: 关闭套接字的接收端。后续对套接字的读操作将立即返回0(表示EOF)。
SHUT_WR: 关闭套接字的发送端。后续对套接字的写操作将返回EPIPE信号(对于TCP)。
SHUT_RDWR: 关闭套接字的接收端和发送端。等同于调用close(sockfd)。
返回值说明
成功:返回0,表示关闭操作成功。
失败:返回-1,并设置errno以指示错误类型。
常见的错误码包括:
EBADF: sockfd不是一个有效的文件描述符。
ENOTSOCK: sockfd不是一个套接字。
EINVAL: howto参数无效。
ENOTCONN: 套接字未连接(对于面向连接的套接字,如TCP)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/898521.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯 之 暴力回溯

文章目录 数字接龙小u的最大连续移动次数问题迷宫 在蓝桥杯中&#xff0c;十分喜欢考察对于网格的回溯的问题&#xff0c;对于这类的问题&#xff0c;常常会使用到这个DFS和BFS进行考察&#xff0c;不过无论怎么考察&#xff0c;都只是会在最基础的模本的基础上&#xff0c;根据…

微信小程序的业务域名配置(通过ingress网关的注解)

一、背景 微信小程序的业务域名配置&#xff08;通过kong网关的pre-function配置&#xff09;是依靠kong实现&#xff0c;本文将通过ingress网关实现。 而我们的服务是部署于阿里云K8S容器&#xff0c;当然内核与ingress无异。 找到k8s–>网络–>路由 二、ingress注解 …

Python数据可视化工具:六西格玛及其基础工具概览

在当今数据驱动的时代&#xff0c;数据分析和可视化工具成为了各行业优化流程、提升质量的关键手段。六西格玛&#xff08;Six Sigma&#xff09;作为一种以数据为基础、追求完美质量的管理理念&#xff0c;其实施依赖于一系列基础工具的灵活运用。而Python&#xff0c;凭借其强…

Spring MVC响应数据

handler方法分析 /*** TODO: 一个controller的方法是控制层的一个处理器,我们称为handler* TODO: handler需要使用RequestMapping/GetMapping系列,声明路径,在HandlerMapping中注册,供DS查找!* TODO: handler作用总结:* 1.接收请求参数(param,json,pathVariable,共享域等…

Python散点图(Scatter Plot):数据探索的“第一张图表”

在数据可视化领域,散点图是一种强大而灵活的工具,它能够帮助我们直观地理解和探索数据集中变量之间的关系。本文将深入探讨散点图的核心原理、应用场景以及如何使用Python进行高效绘制。 后续几篇将介绍高级技巧、复杂应用场景。 Python散点图(Scatter Plot):高阶分析、散点…

【redis】在 Spring中操作 Redis

文章目录 基础设置依赖StringRedisTemplate库的封装 运行StringList删库 SetHashZset 基础设置 依赖 需要选择这个依赖 StringRedisTemplate // 后续 redis 测试的各种方法&#xff0c;都通过这个 Controller 提供的 http 接口来触发 RestController public class MyC…

微服务》》Kubernetes (K8S) 集群 安装

关闭交换空间 # 切换 超级管理员身份 # 查看交换空间 free -h # 关闭交换空间 swapoff -a避免开启启动交换空间 # 注释swap开头的行 vim /etc/fstab关闭防火墙 # 关闭防火墙 # 因为K8S 是集群形式存在的 至少三台 一主二从 &#xff08;一个master 两个node&#xff09…

MySQL 简记

MySQL 简记 mysql中的数据存储的结构是B树 其与B树的相同点是&#xff0c;B树一个节点也可以存放多条数据&#xff0c;并且从左到右依次增大&#xff1b;不同点是&#xff0c;B树的叶子结点之间也能相互连接。那么实际上是采取利用空间换区时间的策略。 那么B树的树结构like…

springboot使用163发送自定义html格式的邮件

springboot使用163发送html格式的邮件 效果: 下面直接开始教学 注册邮箱&#xff0c;生成授权码 获取163邮箱的授权码&#xff0c;可以按照以下步骤操作&#xff1a; 登录163邮箱 打开浏览器&#xff0c;访问 163邮箱登录页面。 使用你的邮箱账号和密码登录。进入邮箱设置 登…

【Kafka】深入了解Kafka

集群的成员关系 Kafka使用Zookeeper维护集群的成员信息。 每一个broker都有一个唯一的标识&#xff0c;这个标识可以在配置文件中指定&#xff0c;也可以自动生成。当broker在启动时通过创建Zookeeper的临时节点把自己的ID注册到Zookeeper中。broker、控制器和其他一些动态系…

Hugging Face预训练GPT微调ChatGPT(微调入门!新手友好!)

Hugging Face预训练GPT微调ChatGPT&#xff08;微调入门&#xff01;新手友好&#xff01;&#xff09; 在实战中&#xff0c;⼤多数情况下都不需要从0开始训练模型&#xff0c;⽽是使⽤“⼤⼚”或者其他研究者开源的已经训练好的⼤模型。 在各种⼤模型开源库中&#xff0c;最…

Redis BitMap 用户签到

Redis Bitmap Bitmap&#xff08;位图&#xff09;是 Redis 提供的一种用于处理二进制位&#xff08;bit&#xff09;的特殊数据结构&#xff0c;它基于 String 类型&#xff0c;每个 bit 代表一个布尔值&#xff08;0 或 1&#xff09;&#xff0c;可以用于存储大规模的二值状…

Nodejs使用redis

框架&#xff1a;koa&#xff0c;通过koa-generator创建 redis: 本地搭建&#xff0c;使用默认帐号&#xff0c;安装说明地址以及默认启动设置&#xff1a;https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/ 中间件&#x…

调研报告:Hadoop 3.x Ozone 全景解析

Ozone 是 Hadoop 的分布式对象存储系统,具有易扩展和冗余存储的特点。 Ozone 不仅能存储数十亿个不同大小的对象,还支持在容器化环境(比如 Kubernetes)中运行。 Apache Spark、Hive 和 YARN 等应用无需任何修改即可使用 Ozone。Ozone 提供了 Java API、S3 接口和命令行接口…

AI学习——卷积神经网络(CNN)入门

作为人类&#xff0c;我们天生擅长“看”东西&#xff1a;一眼就能认出猫狗、分辨红绿灯、读懂朋友的表情……但计算机的“眼睛”最初是一片空白。直到卷积神经网络&#xff08;CNN&#xff09;​的出现&#xff0c;计算机才真正开始理解图像。今天&#xff0c;我们就用最通俗的…

⭐算法OJ⭐二叉树的前序遍历【树的遍历】(C++实现)Binary Tree Preorder Traversal

⭐算法OJ⭐二叉树的中序遍历【树的遍历】&#xff08;C实现&#xff09;Binary Tree Inorder Traversal Given the root of a binary tree, return the preorder traversal of its nodes’ values. Example 1: Input: root [1,null,2,3] Output: [1,2,3]Explanation: Exam…

计算机二级MS之Excel

声明&#xff1a;跟着大猫和小黑学习随便记下一些笔记供大家参考&#xff0c;二级考试之前将持续更新&#xff0c;希望大家二级都能轻轻松松过啦&#xff0c;过了二级的大神也可以在评论区留言给点建议&#xff0c;感谢大家&#xff01;&#xff01; 文章目录 考题难点&#x…

【Linux】VMware Workstation Pro 17 安装教程

目录 安装 VMware Workstation Pro 17 一、CDS Repository 获取安装包 二、网盘获取安装包 三、Broadcom官方获取安装包 后续安装过程没啥特殊要求 安装 VMware Workstation Pro 17 目前VMware Workstation pro 17已经对个人用户免费开放使用。 Broadcom官网地址&#x…

如何在云端平台上建立 30,000 名用户的网页 MMO游戏环境-2 (服务器)

接续上一篇「如何在云端平台上建立 30,000 名用户的网页 MMO游戏环境」&#xff0c;接下来讨论模拟连结上的问题。 最初计划使用35台伺服器来完成这个实验&#xff0c;希望能够有大量的用户连接&#xff0c;以验证真实的连接状况。然而&#xff0c;我们高估了这方面&#xff0c…

架构设计的灵魂交响曲:系统设计各维度的深度解析与实战指南

引言: 系统设计的背景与重要性 在快速变化的技术环境中&#xff0c;数字化转型成为企业生存与发展的核心驱动力。系统设计能力不仅是技术团队的核心竞争力&#xff0c;也是推动业务创新和提升整体效率的关键因素。根据Gartner的研究&#xff0c;超过70%的数字化转型项目未能实…