套接字编程之接口(2)

简介: 套接字:socket(插座、接口)的翻译,通常表示的是系统提供给程序员实现网络通信的一套接口,为啥封装这些接口呢?因为我们知道,网络通信中有很多的协议, 所以在这套接口中就提供了足够充足的选择。我们通常使用的主要是两个协议的通信程序编写:传输层的TCP和UDP协议。

具体操作接口介绍


创建套接字


  #include<sys/types.h>
  #incldue<sys/socket.h>
  int socket(int domain, int type, int protocol);

domain:地址域类型(具体用的是哪种方式,不同的方式有不同的地址结构:ipv4,ipv6,域间通信)

重点记住AF_INET,比较常用

image.png

  1. type:套接字类型
    注意:两种套接字不能混用,你创建的是哪种协议就要用哪个参数
  2. image.png
  3. protocol:协议类型
    注意:默认使用0,则表示使用套接字类型对应的默认协议,注意记住以下俩种:
    (1)IPPROTO_TCP: 值是6
    (2)IPPROTO_UDP:值是17
  4. image.png
  5. 成功返回一个套接字描述符,失败返回:-1;

为套接字绑定地址信息


  int bind(int socket, const struct sockaddr *address,socklen_t address_len);
1.sockfd:返回套接字的描述符
2.addr:要绑定的地址信息(不同地址域类型有不同的地址结构,故需要一个通用的地址结构)

通用地址结构:

 socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及后面要讲的UNIX Domain Socket. 然而, 各种网络协议的地址格式并不相同.

image.png

注意:

 1.IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型, 16位端口号和32位IP地址

 2.IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6. 这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容.

 3.socket API可以都用struct sockaddr *类型表示, 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数;


sockaddr 结构


image.png


sockaddr_in 结构


image.png


image.png

虽然socket api的接口是sockaddr, 但是我们真正在基于IPv4编程时, 使用的数据结构是sockaddr_in; 这个结构里主要有三部分信息: 地址类型, 端口号, IP地址.


in_addr结构


image.png

in_addr用来表示一个IPv4的IP地址. 其实就是一个32位的整数

typedef uint32_t in_addr_t
in_addr_t inet_addr(cosnst char*ip); 

功能:将点分十进制字符串ip地址转化为网络字节序的整数ip地址 ,如:将192.168.2.2->0x0202a8c0

const char *inet_ ntoa(struct in_ addr addr);
功能:将网络字节序整数P地址, 转换为一个点分 十进制字符串地址
struct in_ addr{
  in_ addr_ ts _addr;
}

image.png

发送数据


  ssize_ t sendto(int sockfd, void *buf, size_ _t dlen, int flag, struct sockaddr *peer,socklen_ t alen);

解释:


1.sockfd: socket返回的套接字描述符

2.buf:要发送的数据空间起始地址

3.dlen:要发送的数据长度,从buf地址开始, 发送dlen长度的数据

4.peer设置的是谁的地址,数据就发给谁,peer:对端地址信息,描述了数据要发送给谁

5.flag:默认0- 阻塞发送(发送缓冲区数据满了就等着)

6.alen:对端地址信息长度

7.**返回值:**成功返回实际发送数据字节长度;失败返回-1


接收数据

接收数据

  ssize_ .t recvfrom(int sockfd, void *buf, size. t dlen, int flag, struct sockaddr *peer, socklen _t *alel

解释:


1.sockfd:套接字描述符

2.buf:空间起始地址,接收到的数据就被放入到buf空间中

3.peer用于获取地址信息,peer中存的是谁,数据就是谁发送给我的,peer这个参数是在recvfrom函数中设置的,我们不用设置。peer:接收数据的同时,得直到数据是谁发的,因此这里的peer是个输出参数,用于返回对端地址信息

4.dlen:想要接收的数据长度

5.flag:默认0-阻塞接收(socket接收缓冲区中没有数据就阻塞,直到有数据)

6.alen:地址信息长度,也是一个输入输出参数,表示想要接收的地址信息长度,以及实际得到的地址信息长度

7.返回值:成功返回实际接收到的数据长度;失败返回-1


*注意:凡是涉及到获取地址信息的操作,地址信息都是socklen _t 类型的


关闭套接字


  int close(int fd)

字节序相关接口


主机字节序到网络字节序的转换: uint32_ t htonl(uint32 _ t val); uint16 t htons(uint16_ t val);

网络字节序到主机字节序的转换: uint32_ t ntoh(uint32 _ t val); uint16 _ t ntohs(uint16_ t val);

注意:

 这几个接口中已经进行了主机字节序的判断,因此不需要担心自己的主机字节序,32位数据转换接口,与16转换接口,不能混用

混用出错例子:

image.png

目录
相关文章
|
存储 Cloud Native Linux
C++封装了socket通信类
C++封装了socket通信类
|
6月前
|
存储 算法 网络协议
【探索Linux】P.26(网络编程套接字基本概念—— socket编程接口 | socket编程接口相关函数详细介绍 )
【探索Linux】P.26(网络编程套接字基本概念—— socket编程接口 | socket编程接口相关函数详细介绍 )
60 0
|
11月前
|
网络协议
socket编程函数
socket编程函数
32 0
485通讯接口与232接口的区别
485通讯接口与232接口的区别
2529 1
|
网络协议 安全 定位技术
网络编程概述、网络编程三要素、InetAddress类及端口和协议介绍
网络编程概述、网络编程三要素、InetAddress类及端口和协议介绍
94 0
|
网络协议 程序员 数据格式
套接字编程之接口(1)
套接字编程,通俗的来说:主要讲解的是如何编写一个网络通信程序 1.网络通信的数据汇总都会包含一个完整的为五元组(sip[源端ip地址]、sport[源端端口]、dip[目的端IP地址]dport、protocol[协议]);五元组完成的描述了数据从哪里来到哪里去,用的是什么数据格式。 2.网络通信,通常讨论的是俩个主机之间的通信:客户端&服务端  客户端网络通信程序:通常指的是用户使用的一端  服务端网络通信程序:通常指的是网络编写服务端程序的工作 3.同时我们需要了解:客户端永远都是首先发起服务请求的一端,因为服务器是不知道客户端的地址的,现在用的是动态地址分配,每次上网地址可能发生改变,
76 0
|
测试技术 Python
07 WebSocket接口:如何测试一个完全陌生的协议接口?
07 WebSocket接口:如何测试一个完全陌生的协议接口?
|
网络协议 安全
套接字编程:UDP通信程序编写、套接字接口、字节序转换接口
套接字编程:UDP通信程序编写、套接字接口、字节序转换接口
107 0
套接字编程:UDP通信程序编写、套接字接口、字节序转换接口
套接字编程:UDP通信程序
套接字编程:UDP通信程序
124 0
网络编程基础-Socket编程(使用socketserver实现一对多通信)
由socket模块换成socketserver模块后,改动不大,主要是服务端的代码要进行改动,客户端的代码基本不用动。服务端要继承BaseRequestHandler类。这个类在初始化的时候,它会依次调用3个方法。子类可以覆盖这些方法。
网络编程基础-Socket编程(使用socketserver实现一对多通信)