网络编程(5)套接字地址结构、地址转换

在前面的示例演示代码、socket常用函数中,服务端需要将创建的socket进行bind到本地的struct sockadd_in结构对象上,在服务端accept和客户端connet时,以及sendto/recvfrom中需要传递struct sockaddr对象指针作为参数。

我们在使用过程中需要将地址的文本表达式转换为存放在套接字地址结构中的 二进制数据,需要调用地址转换函数,而这些函数都是与协议相关的。

因此,本节主要说明常用的套接字结构地址,以及地址结构的成员变量,以及相关的函数,另外还介绍用于获取或返回与某个套接字关联的本地/外地的协议地址。

1、套接字地址结构

对于不同的协议族,都定义了不同的套接字地址结构,都是以sockaddr_开头,对应每个协议族的唯一后缀尾。

1.1 IPv4套接字地址结构

typedef uint32_t in_addr_t;
struct in_addr  {
  in_addr_t s_addr;         /* IPv4 address,network byteordered  */
}

struct sockaddr_in {
  sa_family_t sin_family;   /* uint16_t  AF_INET */
  in_port_t sin_port;       /* uint16_t  Port number. network byteordered */
  struct in_addr sin_addr;  /* uint32_t Internet address.  */
	 
  /* Pad to size of `struct sockaddr'.  */
  unsigned char sin_zero[sizeof (struct sockaddr) -
	    sizeof (sa_family_t) - 
	    sizeof (in_port_t) - 
	    sizeof (struct in_addr)];   // 实际是8个字节
}; // 一共 16字节

1.2 IPv6套接字地址结构

struct sockaddr_in6
{
  sa_family_t sin6_family;   /* uint16_t  AF_INET6 */
  in_port_t sin6_port;	     /* uint16_t  Transport layer port # */
  uint32_t sin6_flowinfo;	 /* uint32_t  IPv6 flow information */
  struct in6_addr sin6_addr; /* 128bits   IPv6 address */
  uint32_t sin6_scope_id;	 /* uint32_t  IPv6 scope-id */
}; // 一共 28 字节

1.3 通用套接字地址结构

struct sockaddr {
  sa_family_t sin_family;  /* uint16_t  AF_INET */
  char sa_data[14];        /* 14 Bytes  Address data. */
} // 16字节

Socket的函数地址参数基本都是sockaddr结构,根据实际传入的第二个参数地址结构长度来决定解析哪一种套接字地址结构。

1.4 新的通用套接字地址结构

#define __ss_aligntype	unsigned long int
#define _SS_PADSIZE (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof(__ss_aligntype)) // 118
struct sockaddr_storage
{
  sa_family_t ss_family;	        /* 2 Bytes Address family, etc.  */
  char __ss_padding[_SS_PADSIZE];  /* 118 Bytes   */
  __ss_aligntype __ss_align;	   /* 8 Bytes Force desired alignment.  */
}; // 128 字节

sockaddr_storage类型满足对齐、空间足够大,内容透明,需要强制转换成适用于ss_family字段对应的地址类型套接字地址结构。

2、套接字地址相关函数

2.1 网络字节序

网络协议必须指定网络字节序,即大端字节序。大端字节序下,数据的高位数据保存在内存区的高地址上。
在这里插入图片描述
主机字节序和网络字节序的转换函数有

#include <netinet/in.h>
uint32_t ntohl (uint32_t __netlong);
uint16_t ntohs (uint16_t __netshort);	// 返回主机字节序
uint32_t htonl (uint32_t __hostlong);
uint16_t htons (uint16_t __hostshort); 	// 返回网络字节序

函数后缀虽然是l和s(long和short),但是long这里实际还是32位的值。在小端操作系统中会进行大小端转换,大端操作系统实际是一个空宏,不做转换。

2.2 字节操作

多字节的操作函数有两组,不对数据作解释,也不假设数据是以空字符结束的C字符串。以空字符结尾的C字符串是头文件<string.h>中以str(表示字符串)开头的函数处理的。

#include <string.h>
void *memset(void *src, void *dest, int c, size_t len);
void *memcopy(void *dest, const void *src, size_t nbytes); // 重叠时使用memmove
int   memcmp(const void *ptr1, const void *ptr2, size_t nbytes);  

名字以b(表示字节)开头的函数起源于4.2 BSD,以mem(表示内存)开头的函数在支持ANSI C函数库的系统都支持。

#include <strings.h>
void bzero(void *dest, size_t nbytes);
void bcopy(void *src, void *dest, size_t nbytes);// 重叠正常
int  bcmp(void *ptr1, void *ptr2, size_t nbytes);  

2.3 地址转换

介绍在ASCII字符串格式(点分二进制数串)与网络字节序的二进制数据之间转换网络地址

(1)inet_aton、inet_addr和inet_ntoa

点分十进制数串(如“192.168.3.123”)与长度为32位的网络字节序IPv4地址转换。

#include <arpa/inet.h>
int net_aton(const char *strptr, struct in_addr *addrptr);  //转换成功返回1,否则返回0
in_addr_t inet_addr(const char *strptr);  //字符串有效返回32位IPv4地址,否则返回INADDR_NONE 
char *inet_ntoa(struct in_addr addrptr);  //返回点分十进制数串的字符指针

函数inet_addr()失败返回0xffffffff,实际是”255.255.255.255”的广播地址,有些手册出错时返回-1,已经废弃,使用新版的inet_aton函数;inet_ntoa函数仅支持IPv4地址转换,且是不可重入(有其他多个函数体重公用一个全局变量,多线程会有问题),建议使用新版的inet_ntop函数。

(2)inet_pton、inet_ntop

这两个函数是随IPv6出现的,也支持IPv4地址转换,并且都是可重入的。函数名中p和n分别表示表达presentation和数值numeric。地址的表达格式是ASCII字符串,数值格式是存放在套接地址结构中的二进制值。

#include <arpa/inet.h>
int         inet_pton(int family, const char *srcptr, void *addrptr);  // 转换成功返回1,无效字符串返回0,出错返回-1
const char *inet_ntop(int family, const void *addrptr, char *srcptr, size_t len);	//返回结果指针,出错返回NULL

注意第一个函数net_pton()的返回结果:转换成功返回1,无效字符串返回0,出错返回-1
两个函数的参数family可以是AF_INET、AF_INET6。第二个函数的len参数是目标存储单元的大小,为避免超过缓冲区长度,定义了两个宏

#include <arpa/inet.h>
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46

在IPv4地址转换中,我们可以替换老代码

// 老代码
foo.sin_addr.s_addr = inet_addr(cp);  
// 新代码  
itet_pton(AF_INET, cp, &foo.sin_addr);
// 老代码
char *ptr = inet_ntoa(foo.sin_addr);  
// 新代码     
char str[INET_ADDRLEN];  
ptr = inet_ntop(AF_INET, &foo.sin_addr, str, INET_ADDRLEN);

2.4 地址操作

套接字的地址处理主要在两个地方,第一个是构建struct sockaddr_in和struct sockaddr_in6地址结构用于bind()或connect()或sendto(),第二个是用在recvfrom()以获取struct sockaddr_in或struct sockaddr_in6。

(1)构建地址结构

struct sockaddr_in和struct sockaddr_in6的构建,分别如下

struct sockaddr_in addr_in4;
// 初始化内存(若ip和ort都赋值非零值,可去掉)
//memset(&addr_in4,0,sizeof(addr_in4));
// 协议地址族
addr_in4.sin_family = AF_INET; // IPv4
// 地址赋值
const char ip4_addr[] = "192.168.3.100";
addr_in4.sin_addr.s_addr = INADDR_ANY;            //INADDR_ANY=0, 内核选择
addr_in4.sin_addr.s_addr = inet_addr(ip4_addr);   //废弃,仅IPv4
inet_aton(ip4_addr, &addr_in4.sin_addr);          // 仅IPv4
inet_pton(AF_INET, ip4_addr, &addr_in4.sin_addr); // 通用IPv4/6,建议
// 端口赋值
addr_in4.sin_port = 0;          // 内核选择
ddr_in4.sin_port = htons(8080); //网络序

使用ip addr查看本机的ipv6地址
在这里插入图片描述

struct sockaddr_in6 addr_in6;
memset(&addr_in6, 0, sizeof(addr_in6));
// 协议地址族
addr_in6.sin6_family = AF_INET6; // IPv6
// 地址赋值
const char ip6_addr[] = "fe80::30bb:634b:434:bca4";
addr_in6.sin6_addr = IN6ADDR_ANY_INIT; // 内核选择
addr_in6.sin6_addr.s6_addr16[0] = htons(std::stoi("fe80",0,16));
addr_in6.sin6_addr.s6_addr16[1] = 0;
addr_in6.sin6_addr.s6_addr16[2] = 0;
addr_in6.sin6_addr.s6_addr16[3] = 0;//手动赋值
addr_in6.sin6_addr.s6_addr16[4] = htons(std::stoi("30bb",0,16));
addr_in6.sin6_addr.s6_addr16[5] = htons(std::stoi("634b",0,16));
addr_in6.sin6_addr.s6_addr16[6] = htons(std::stoi("434",0,16));
addr_in6.sin6_addr.s6_addr16[7] = htons(std::stoi("bca4",0,16)); 
inet_pton(AF_INET6, ip6_addr, &addr_in6.sin6_addr);  // 建议
// 端口赋值
addr_in6.sin6_port = 0;           // 内核选择
addr_in6.sin6_port = htons(8080); //网络序

(2)获取地址结构

这里给出服务端recvform代码的部分示例,是修改之前udp简单通信代码,如下

struct sockaddr_storage storage; 
socklen_t socklen = sizeof(storage);  // 区别是ipv4,还是ipv6

int len = ::recvfrom(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&storage, &socklen);

if (len < 0){
  printf("%s: recv failed. err %s \n", __func__, strerror(errno));  
}
else{
  // 获取客户端的ip、和port
  char ip[INET6_ADDRSTRLEN];   
  int port;
  // 根据socklen长度值,确认
  if(socklen == sizeof(sockaddr_in))  { //Ipv4   
    sockaddr_in  clientaddr = *(sockaddr_in*)&storage;
    inet_ntop(AF_INET, &clientaddr.sin_addr, ip, socklen);      
    port = ntohs(clientaddr.sin_port);     
    printf("%s: client [%s:%d] recv %2d: %s\n", __func__, ip, port, len, buf);
  }
  else if(socklen == sizeof(sockaddr_in6))  { //Ipv6   
    sockaddr_in6 clientaddr = *(sockaddr_in6*)&storage;
    inet_ntop(AF_INET6, &clientaddr.sin6_addr, ip, socklen);      
    port = ntohs(clientaddr.sin6_port);
	printf("%s: client [%s:%d] recv %2d: %s\n", __func__, ip, port, len, buf);
  }
}

结果示例
在这里插入图片描述

3、套接字关联的本地/外地地址

在网络通信中,TCP服务端可能需要知道当前建立连接的客户端地址,或者UDP/TCP客户端未调用bind函数绑定本地地址、或者bind时仅指定ip或port中的一个,需要知道内核分配的地址信息,就需要用到如下两个函数:

#include <sys/socket.h>
int getpeername (int sockfd, struct sockaddr *localaddr, socklen_t * addrlen);
int getsockname (int sockfd, struct sockaddr *peeraddr, socklen_t * addrlen);  // 成功返回0,出错返回-1

这两个函数的使用方式,参看后面的TCP套接字编程。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章。 Linux网络编程之TCP/IP基础篇 Linux网络编程socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口) 02TCPIP基础(二) 最大传输单元(MTU)/路径MTU 以太网帧格式 ICMP ARP RARP 03TCPIP基础(三) IP数据报格式 网际校验和 路由 04TCPIP基础(四) TCP特点 TCP报文格式 连接建立三次握手 连接终止四次握手 TCP如何保证可靠性 05TCPIP基础(五) 滑动窗口协议 UDP特点 UDP报文格式 Linux网络编程socket编程篇 06socket编程(一) 什么是socket IPv4套接口地址结构 网络字节序 字节序转换函数 地址转换函数 套接字类型 07socket编程(二) TCP客户/服务器模型 回射客户 /服务器 socket、bind、listen、accept、connect 08socket编程(三) SO_REUSEADDR 处理多客户连接(process-per-conection) 点对点聊天程序实现 09socket编程(四) 流协议与粘包 粘包产生的原因 粘包处理方案 readn writen 回射客户/服务器 10socket编程(五) read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、连接终止四次握手 TIME_WAIT与SO_REUSEADDR SIGPIPE 13socket编程(八) 五种I/O模型 select 用select改进回射客户端程序 14socket编程(九) select 读、写、异常事件发生条件 用select改进回射服务器程序。 15socket编程(十) 用select改进第八章点对点聊天程序 16socket编程(十一) 套接字I/O超时设置方法 用select实现超时 read_timeout函数封装 write_timeout函数封装 accept_timeout函数封装 connect_timeout函数封装 17socket编程(十二) select限制 poll 18socket编程(十三) epoll使用 epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 Linux网络编程之进程间通信篇 23进程间通信介绍(一) 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对象的持续性 24进程间通信介绍(二) 死锁 信号量 PV原语 用PV原语解决司机与售票员问题 用PV原语解决民航售票问题 用PV原语解决汽车租赁问题 25System V消息队列(一) 消息队列 IPC对象数据结构 消息队列结构 消息队列在内核中的表示 消息队列函数 26System V消息队列(二) msgsnd函数 msgrcv函数 27System V消息队列(三) 消息队列实现回射客户/服务器 28共享内存介绍 共享内存 共享内存示意图 管道、消息队列与共享内存传递数据对比 mmap函数 munmap函数 msync函数 29System V共享内存 共享内存数据结构 共享内存函数 共享内存示例 30System V信号量(一) 信号量 信号量集结构 信号量集函数 信号量示例 31System V信号量(二) 用信号量实现进程互斥示例 32System V信号量(三) 用信号集解决哲学家就餐问题 33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux网络编程之线程篇 36线程介绍 什么是线程 进程与线程 线程优缺点 线程模型 N:1用户线程模型 1:1核心线程模型 N:M混合线程模型 37POSIX线程(一) POSIX线程库相关函数 用线程实现回射客户/服务器 38POSIX线程(二) 线程属性 线程特定数据 39POSIX信号量与互斥锁 POSIX信号量相关函数 POSIX互斥锁相关函数 生产者消费者问题 自旋锁与读写锁介绍 40POSIX条件变量 条件变量 条件变量函数 条件变量使用规范 使用条件变量解决生产者消费者问题 41一个简单的线程池实现 线程池性能分析 线程池实现 网络编程, Linux
教程非常不错,价值280元,绝对是干货 Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章。 Linux网络编程之TCP/IP基础篇 Linux网络编程socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口) 02TCPIP基础(二) 最大传输单元(MTU)/路径MTU 以太网帧格式 ICMP ARP RARP 03TCPIP基础(三) IP数据报格式 网际校验和 路由 04TCPIP基础(四) TCP特点 TCP报文格式 连接建立三次握手 连接终止四次握手 TCP如何保证可靠性 05TCPIP基础(五) 滑动窗口协议 UDP特点 UDP报文格式 Linux网络编程socket编程篇 06socket编程(一) 什么是socket IPv4套接口地址结构 网络字节序 字节序转换函数 地址转换函数 套接字类型 07socket编程(二) TCP客户/服务器模型 回射客户/服务器 socket、bind、listen、accept、connect 08socket编程(三) SO_REUSEADDR 处理多客户连接(process-per-conection) 点对点聊天程序实现 09socket编程(四) 流协议与粘包 粘包产生的原因 粘包处理方案 readn writen 回射客户/服务器 10socket编程(五) read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、连接终止四次握手 TIME_WAIT与SO_REUSEADDR SIGPIPE 13socket编程(八) 五种I/O模型 select 用select改进回射客户端程序 14socket编程(九) select 读、写、异常事件发生条件 用select改进回射服务器程序。 15socket编程(十) 用select改进第八章点对点聊天程序 16socket编程(十一) 套接字I/O超时设置方法 用select实现超时 read_timeout函数封装 write_timeout函数封装 accept_timeout函数封装 connect_timeout函数封装 17socket编程(十二) select限制 poll 18socket编程(十三) epoll使用 epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 Linux网络编程之进程间通信篇 23进程间通信介绍(一) 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对象的持续性 24进程间通信介绍(二) 死锁 信号量 PV原语 用PV原语解决司机与售票员问题 用PV原语解决民航售票问题 用PV原语解决汽车租赁问题 25System V消息队列(一) 消息队列 IPC对象数据结构 消息队列结构 消息队列在内核中的表示 消息队列函数 26System V消息队列(二) msgsnd函数 msgrcv函数 27System V消息队列(三) 消息队列实现回射客户/服务器 28共享内存介绍 共享内存 共享内存示意图 管道、消息队列与共享内存传递数据对比 mmap函数 munmap函数 msync函数 29System V共享内存 共享内存数据结构 共享内存函数 共享内存示例 30System V信号量(一) 信号量 信号量集结构 信号量集函数 信号量示例 31System V信号量(二) 用信号量实现进程互斥示例 32System V信号量(三) 用信号集解决哲学家就餐问题 33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux网络编程之线程篇 36线程介绍 什么是线程 进程与线程 线程优缺点 线程模型 N:1用户线程模型 1:1核心线程模型 N:M混合线程模型 37POSIX线程(一) POSIX线程库相关函数 用线程实现回射客户/服务器 38POSIX线程(二) 线程属性 线程特定数据 39POSIX信号量与互斥锁 POSIX信号量相关函数 POSIX互斥锁相关函数 生产者消费者问题 自旋锁与读写锁介绍 40POSIX条件变量 条件变量 条件变量函数 条件变量使用规范 使用条件变量解决生产者消费者问题 41一个简单的线程池实现 线程池性能分析 线程池实现 网络编程, Linux, 密码
Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章。 Linux网络编程之TCP/IP基础篇 Linux网络编程socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口) 02TCPIP基础(二) 最大传输单元(MTU)/路径MTU 以太网帧格式 ICMP ARP RARP 03TCPIP基础(三) IP数据报格式 网际校验和 路由 04TCPIP基础(四) TCP特点 TCP报文格式 连接建立三次握手 连接终止四次握手 TCP如何保证可靠性 05TCPIP基础(五) 滑动窗口协议 UDP特点 UDP报文格式 Linux网络编程socket编程篇 06socket编程(一) 什么是socket IPv4套接口地址结构 网络字节序 字节序转换函数 地址转换函数 套接字类型 07socket编程(二) TCP客户/服务器模型 回射客户/服务器 socket、bind、listen、accept、connect 08socket编程(三) SO_REUSEADDR 处理多客户连接(process-per-conection) 点对点聊天程序实现 09socket编程(四) 流协议与粘包 粘包产生的原因 粘包处理方案 readn writen 回射客户/服务器 10socket编程(五) read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、连接终止四次握手 TIME_WAIT与SO_REUSEADDR SIGPIPE 13socket编程(八) 五种I/O模型 select 用select改进回射客户端程序 14socket编程(九) select 读、写、异常事件发生条件 用select改进回射服务器程序。 15socket编程(十) 用select改进第八章点对点聊天程序 16socket编程(十一) 套接字I/O超时设置方法 用select实现超时 read_timeout函数封装 write_timeout函数封装 accept_timeout函数封装 connect_timeout函数封装 17socket编程(十二) select限制 poll 18socket编程(十三) epoll使用 epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 Linux网络编程之进程间通信篇 23进程间通信介绍(一) 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对象的持续性 24进程间通信介绍(二) 死锁 信号量 PV原语 用PV原语解决司机与售票员问题 用PV原语解决民航售票问题 用PV原语解决汽车租赁问题 25System V消息队列(一) 消息队列 IPC对象数据结构 消息队列结构 消息队列在内核中的表示 消息队列函数 26System V消息队列(二) msgsnd函数 msgrcv函数 27System V消息队列(三) 消息队列实现回射客户/服务器 28共享内存介绍 共享内存 共享内存示意图 管道、消息队列与共享内存传递数据对比 mmap函数 munmap函数 msync函数 29System V共享内存 共享内存数据结构 共享内存函数 共享内存示例 30System V信号量(一) 信号量 信号量集结构 信号量集函数 信号量示例 31System V信号量(二) 用信号量实现进程互斥示例 32System V信号量(三) 用信号集解决哲学家就餐问题 33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux网络编程之线程篇 36线程介绍 什么是线程 进程与线程 线程优缺点 线程模型 N:1用户线程模型 1:1核心线程模型 N:M混合线程模型 37POSIX线程(一) POSIX线程库相关函数 用线程实现回射客户/服务器 38POSIX线程(二) 线程属性 线程特定数据 39POSIX信号量与互斥锁 POSIX信号量相关函数 POSIX互斥锁相关函数 生产者消费者问题 自旋锁与读写锁介绍 40POSIX条件变量 条件变量 条件变量函数 条件变量使用规范 使用条件变量解决生产者消费者问题 41一个简单的线程池实现 线程池性能分析 线程池实现 网络编程, Linux, 密码
### 回答1: 在网络编程中,C++的STL(Standard Template Library)是一个非常有用的工具。STL提供了许多数据结构和算法,可以帮助我们更轻松地处理网络编程中的各种任务。 首先,STL的容器类是网络编程中经常用到的数据结构。例如,我们可以使用STL的vector来存储动态大小的数组,非常适用于存储和处理网络数据。此外,STL的map和unordered_map类可以用于构建键值对结构,方便快速地查找和操作网络数据。 STL还提供了一系列的算法,可以用于处理网络编程中的常见任务。例如,我们可以使用STL的sort算法对网络数据进行排序,使用STL的find算法查找某个特定的数据,或者使用STL的accumulate算法计算网络数据的总和。这些算法能够在网络编程中提高代码的效率和可读性。 此外,STL还提供了一些其他功能,如字符串处理和输入输出操作等,这些功能在网络编程中也非常有用。 总之,C++的STL在网络编程中是一个强大且方便的工具。它提供了多种数据结构和算法,可以帮助我们更轻松地处理网络数据,并提高代码的效率和可读性。无论是处理数据、查找特定的值还是进行计算,STL都能够提供相应的功能,使网络编程变得更加简单和高效。 ### 回答2: C++ STL(标准模板库)是C++语言的一个重要部分,它提供了一系列的模板类和函数,用于实现常用的数据结构和算法。网络编程是指利用计算机网络进行数据传输和通信的一种编程方式。 在C++中使用STL进行网络编程时,可以使用STL提供的一些容器类和算法来简化网络编程的过程。例如,使用vector可以方便地管理接收或发送的数据;使用algorithm库中的函数可以快速处理数据;使用string类可以方便地操作字符串等。 对于网络编程,C++ STL没有直接提供相应的网络编程接口,而是需要借助于操作系统提供的网络编程库(如Socket套接字编程)来实现网络通信。通过将底层的网络库和STL进行结合,可以更加方便和高效地编写网络应用程序。 在网络编程中,可以使用STL中的容器类来存储和管理从网络中接收到的数据,例如使用vector来存储接收到的数据包,或者使用list来保存已连接的客户端。同时,可以使用STL中的算法来处理这些数据,例如使用find函数查找数据包中的特定元素。 除此之外,STL还提供了一些有用的函数和类,例如thread类可以用于多线程编程,用于处理并发的网络请求;atomic类可以保证对共享数据的原子性操作,用于实现线程安全的网络通信。 总而言之,C++ STL是C++编程中的重要工具,它提供了一系列的模板类和函数,可以方便地实现网络编程中的数据管理和算法处理,而网络编程则是利用计算机网络进行数据传输和通信的一种编程方式。 ### 回答3: C++ STL(Standard Template Library)是一组标准库,提供了许多常用的数据结构和算法。它包含的容器类(如vector、list、map等)可以方便地存储和操作数据,而提供的算法则可以实现一些常用的数据处理操作(如排序、查找等)。 在网络编程方面,C++ STL可以使用socket库(socket.h)来实现网络通信。通过socket库,可以创建网络套接字socket),并使用套接字进行数据的收发。 C++ STL中的vector可以被用来存储接收和发送的数据,可以使用其成员函数push_back()向vector中添加数据,使用operator[]访问vector中的数据。使用vector的好处是可以动态调整容器大小,使得数据存储更加方便。 通过网络套接字的recv()函数可以接收网络中传来的数据,而send()函数可以将数据发送到网络中。需要注意的是,在使用recv()函数接收数据时,应该使用一个循环来确保接收到完整的数据。可以使用std::string和字符数组来存储接收和发送的数据。 除了基本的网络通信,C++ STL还提供了一些辅助函数,用于解析和构造网络地址。例如,使用inet_ntoa()函数可以将IP地址从网络字节顺序转换为字符串形式,而inet_aton()函数则可以将IP地址从字符串形式转换为网络字节顺序。 总而言之,C++ STL可以在网络编程中提供丰富的数据结构和算法,使开发者可以更加轻松地实现各种网络应用。使用网络套接字和STL提供的功能,可以实现数据的发送和接收,并对数据进行各种处理和操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aworkholic

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值