套接字的地址结构,IP地址转换函数,网络编程的接口

目录

一、套接字的地址结构

1.1 通用socket地址结构

1.2 专用socket地址结构

1.2.1 tcp协议族

1.2.3 IP协议族

二、IP地址转换函数

三、网络编程接口

3.1 socket()

3.2 bind()

3.3 listen()

3.4 accept()

3.5 connect()

3.6 close()

3.7 recv()、send()

3.8 recvfrom()、sento()


一、套接字的地址结构

我们前面所讨论的IPC机制都依靠一台计算机系统的共享资源实现,这里的资源可以是文件系统空间,共享的物理内存或者消息队列,但只有运行在同一台机器上的进程才能使用它们.

一台机器上的进程可以使用套接字和另外一台机器上的进程通信,这样就可以支持分布在网络中的客户/服务器系统.

同一台机器上的进程之间也可以使用套接字进行通信,

套接字的特性由3个属性确定,它们是:域(domain),类型(type)和协议(protocol).

套接字用地址作为它的名字,地址的格式随域(又被称为协议族,protocol family)的不同而不同,每个协议族又可以使用一个或多个地址族来定义地址格式,

1.1 通用socket地址结构

socket 网络编程接口中表示 socket 地址的是结构体 sockaddr,其定义如下:

#include <bits/socket.h>
struct sockaddr
{
    sa_family_t sa_family;//协议族
    char sa_data[14];//数据,没有给出IP地址,就是给了这么一块儿空间,起了一个占位的作用。
};

sa_familvy 成员是地址族类型(sa_family_t)的变量。地址族类型通常与协议族类型对应。常见的协议族和对应的地址族如下图所示:

1.2 专用socket地址结构

TCP/IP 协议族有 sockaddr_in 和 sockaddr_in6 两个专用 socket 地址结构体,它们分别用于 IPV4 和 IPV6:

  • sin_family:地址族 AF INET
  • sin_port:端口号,需要用网络字节序表示
  • sin_addr:IPV4 地址结构:s_addr 以网络字节序表示 IPV4 地址
struct in_addr
{
    u_int32_t s_addr;//无符号的32位的整型,存放IP地址;
};

1.2.1 tcp协议族

tcp协议族主要有三个:

  • 地址族
  • 端口号
  • IP地址
//tcp协议族
struct sockaddr_in
{
    sa_family_t sin_family;//地址族,就是sin_family:地址族 AF_INET
    u_int16_t sin_port;//端口,16位的端口
    struct in_addr sin_addr;//一个结构体,只有一个成员,是无符号的32位的整型,存放IP地址;(IPV4的地址就是32位)
    //其实后面还有占位的,只是我们不用它,所以就没有写
};

1.2.3 IP协议族

//IP协议族
struct in6_addr
{
    unsigned char sa_addr[16];// IPV6 地址,要用网络字节序表示
};

struct sockaddr_in6
{
    sa_family_t sin6_family;//地址族:AF_INET6
    u_inet16_t sin6_port;// 端口号:用网络字节序表示
    u_int32_t sin6_flowinfo;// 流信息,应设置为 0
    struct in6_addr sin6_addr;// IPV6 地址结构体
    u_int32_t sin6_scope_id;// scope ID,尚处于试验阶段
};

二、IP地址转换函数

通常,人们习惯用点分十进制字符串表示 IPV4 地址,但编程中我们需要先把它们转化为整数方能使用,下面函数可用于点分十进制字符串表示的IPV4 地址和网络字节序整数表示的 IPV4 地址之间的转换

#include <arpa/inet.h>
in_addr_t inet_addr(const char *cp);//字符串表示的 IPV4 地址转化为网络字节序
char* inet_ntoa(struct in_addr in);// IPV4 地址的网络字节序转化为字符串表示

三、网络编程接口

头文件:

#include <sys/types.h>
#include <sys/socket.h>

3.1 socket()

socket()创建套接字,成功返回套接字的文件描述符,失败返回-1

int socket(int domain, int type, int protocol);
  • domain:设置套接字的协议族,AF_UNIX 、AF_INET、 AF_INET6
  • type:设置套接字的服务类型 SOCK_STREAM(流式服务)、SOCK_DGRAM(数据报服务)
  • protocol:一般设置为 0,表示使用默认协议
     

3.2 bind()

bind()将 sockfd 与一个 socket 地址绑定,成功返回 0,失败返回-1

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfd 是网络套接字描述符,(命名套接字,就是上面的函数的返回值作为了我们的参数sockfd)
  • addr 是地址结构
  • addrlen 是 socket 地址的长度

3.3 listen()

listen()创建一个监听队列以存储待处理的客户连接,成功返回 0,失败返回-1

int listen(int sockfd,int backlog);
  • sockfd 是被监听的 socket 套接字
  • back1og 表示处于完全连接状态的 socket 的上限

3.4 accept()

accept()从 listen 监听队列中接收一个连接,成功返回一个新的连接 socket,该 socket 唯一地标识了被接收的这个连接,失败返回-1

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • sockfd 是执行过 listen 系统调用的监听 socket
  • addr 参数用来获取被接受连接的远端 socket 地址
  • addrlen 指定该 socket 地址的长度

3.5 connect()

客户端需要通过此系统调用来主动与服务器建立连接,成功返回 0,失败返回-1

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
  • sockfd 参数是由 socket()返回的一个 socket
  • serv_addr 是服务器监听的 socket 地址
  • addrlen 则指定这个地址的长度

3.6 close()

关闭一个连接,实际上就是关闭该连接对应的socket

int close(int sockfd);

3.7 recv()、send()

TCP 数据读写:

ssize_t recv(int sockfd, void *buff, size_t len, int flags);

ssize_t send(int sockfd, const void *buff, size_t len, int flags);
  • recv()读取 sockfd 上的数据,buff 和 len 参数分别指定读缓冲区的位置和大小
  • send()往 socket 上写入数据, buff 和 len 参数分别指定写缓冲区的位置和数据长度
  • flags 参数为数据收发提供了额外的控制

3.8 recvfrom()、sento()

UDP 数据读写:

recvfrom()读取 sockfd 上的数据, buff 和 len 参数分别指定读缓冲区的位置和大小

ssize_t recvfrom(int sockfd, void *buff, size_t len, int flags.struct sockaddr* src_addr,socklen_t* addrlen);
  • src_addr 记录发送端的 socket 地址
  • addrlen 指定该地址的长度

sendto()往 socket 上写入数据, buff 和 len 参数分别指定写缓冲区的位置和数据长度

ssize_t sendto(int sockfd, void *buff, size_t len, int flags,struct sockaddr* dest_addr,socklen_t addrlen);
  • dest_addr 指定接收数据端的 socket 地址
  • addrlen 指定该地址的长度
  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值