网络编程套接字(一)

网络基础概念

网络协议初识

OSI七层模型:

物理层,数据链路层,网络层,传输层,会话层,表示层,应用层

TCP/IP五层模型
  • 应用层:负责应用程序之间的数据传输,程序员就是工作在这一层面
    典型的协议:HTTP协议,FTP协议,DNS协议,SMTP协议
  • 传输层:负责端与端之间的数据传输
    典型的协议:TCP协议,UDP协议
  • 网络层:负责路由选择和地址管理
    典型的协议:IP协议,ICMP协议,典型的设备:路由器
  • 数据链路层:负责相邻设备之间的数据帧传输的
    典型的协议:以太网 典型的设备:交换机
  • 物理层:负责光电信号传输
    典型的协议:以太网协议 典型的设备:集线器

IP地址和端口

IP地址(ipv4):
作用:在网络当中唯一标识一台主机
本质:unit32_t值,无符号4个字节,最大范围是42亿多
采用点分十进制,每个字节最大能够表示的数字为255
ip地址分为源ip地址和目的ip地址

网络通信中,每一条数据都是需要具备5条信息
5元组=源IP地址+源端口+目的ip地址+目的端口+protocol
ipv6:
1.ipv4和ipv6指的是不同版本的ip协议
2.ipv6并不向下兼容ipv4,原因就是两者的ip协议的报头格式都是不一样
3.ipv6是16字节的整数,2^128

port:

  • 1.端口是在一台主机当中标识一个进程
  • 2.本质:unit16_t端口的范围为0~ 2^16(0~ 65535)其中0~1023是知名端口,mysql是3306端口,oracle是1521端口
  • 3.网络当中的程序,通信的时候,都是需要使用端口进行通信的
  • 4.IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;
  • 5.一个端口号只能被一个进程占用.

TCP和UDP

TCP:传输层协议

  • 面向连接:tcp的网络通信双方在发送数据之气需要先建立连接,才可以发送数据
  • 可靠传输:保证TCP数据包可靠的到达对端
  • 面向字节流:对于TCP数据可以随意的存取

UDP:传输层协议

  • 无连接:UDP通信的双方在发送数据之前不需要建立连接,只需要知道对方的ip和port就可以直接发送
  • 不可靠:如果UDP数据在网络当中传输的时候,丢失掉了,则不会保证udp数据一定到达对端了
  • 面向数据报:UDP在发送数据的时候,是整条发送整条接收的

网络字节序

字节序:CPU对内存当中的数据进行存取的顺序
大端字节序:低地在这里插入图片描述址存高位
小端字节序:低地址存高位
0x01020304 当中,01为高地址位,04为低地址位

x86_64架构的机器都是小端字节序
网络字节序:大端字节序
小端机器和大端机器进行通信的时候,如果不转换字节序,则会造成小端机器很小的数字,经过网络传输,被大端机器读成很大的数字

主机字节序:代表的是当前机器的字节序
字节序的转换:
大端字节序转换成网络字节序----》网络字节序就是大端字节序

  • unit32_t htonl(unit32_t hostlog):将32位的主机字节序转换成网络字节序,即小端字节序转换成大端字节序
  • unit32_t ntohl(unit32_t netlog):将32位的网络字节序转换成主机字节序
  • unit16_t htons(unit16_t hostshort):将16位的主机字节序转换成网络字节序
  • unit16_t ntohs(unit16_t netshort):将16位的网络字节序转换成主机字节序

h表示host,n表示network,l表示32位长整数,s表示16位短整数。

socket编程接口

创建套接字(TCP/UDP,客户端+服务器)

int socket(int domain,int type,int protocol)

  • domain:地址域,设置网络层使用什么协议
    网络层:ipv4–》AF_INET
    ipv6—>AF_INET6
  • type:套接字类型
    传输层:tcp/udp
    流式套接字:默认协议是tcp,不支持udp–》SOCK_STREAM
    数据报套接字:默认协议是udp,不支持tcp—》SOCK_DGRAM
  • protocol:指定套接字使用的协议
    0:采用套接字默认的类型
    IPPROTO_TCP—>6
    IPPROTO_UDP—>17
  • 返回值:返回套接字的操作句柄,其实就是一个文件描述符,我们称之为套接字描述符
绑定地址信息(TCP/UDP,服务器)

int bind(int sockfd,const sockaddr*addr,socklen_t addrlen)
sock:套接字操作句柄
addr:地址信息 ip+port

struct sockaddr
{
sa_family_t sa_family; //填充地址域,告诉bind函数,网络层使用什么协议
char sa_data[14];  //填充地址信息,IP+PORT

}
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);//2个字节的地址域信息 AF_INET
    in_port_t sin_port;                /*typedef uint16_t in_port_t; *///两个字节的无符号整数
    struct in_addr sin_addr;            /* Internet address.  */四个字节的无符号整数

   /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
                           __SOCKADDR_COMMON_SIZE -
                           sizeof (in_port_t) -
                           sizeof (struct in_addr)];
  };
typedef uint32_t in_addr_t;                                          
struct in_addr
  {                                                                    
    in_addr_t s_addr;                                            
  };  
  • IPv4和IPv6的地址格式定义在 /usr/include/netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型, 16位端口号和32位IP地址.
  • IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6. 这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容.
  • socket API可以都用struct sockaddr *类型表示, 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数;

bind接口在设计的时候为了通用各种协议,定义了一个结构体struct sockaddr;而在进行具体协议地址信息绑定的时候,填充不同的结构体,之后将结构体的对象的地址,强转传参给bind函数

socklen:地址信息的长度,防止有的协议地址信息长度大于16个字节,所以传递地址信息长度,告诉bind函数,应该如何去解析地址信息

发送数据

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);

  • sockfd:套接字描述符
  • buf:待发送的数据
  • len:发送数据的长度
  • flags:0表示阻塞
  • dest_addr:目标主机地址信息
  • addrlen:地址信息长度
    1.UDP也是有发送缓冲区的,只不过UDP的特点是整条发送,所以在发送的缓冲区当中加上UDP的协议报头之后就直接提交给网络层
    2.阻塞发送的含义:当发送缓冲区当中有数据的时候,再次调用sendto接口,会阻塞等待,直到上一条数据发送完毕,sendto才会将数据写到发送缓冲区当中
接收数据

size_t recvfrom(int sockfd,void* buf,size_t len,int flags,struct sockaddr* src_addr,socklen_t* addrlen);

  • sockfd:套接字描述符
  • buf:从接收缓冲区当中拿到数据放到哪一个buffer当中
  • len:buffer的最大长度,意味着最大可以接收多少数据,预留’\0’的位置
  • flags:0:阻塞
  • src_addr:源主机的地址信息(标识这条数据从哪一个主机上面的哪一个进程来)
  • addrlen:地址信息长度,同时是一个输入输出型参数
关闭套接字

close(int sockfd)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值