Linux:udp socket编程

ip+端口=套接字,现在所说的socket编程就是套接字编程

编程流程

对于网络编程要从客户端和服务端来看,在网络通信前,双方都要做准备工作:

对于服务端

1.创建套接字
2.绑定地址信息


绑定地址信息是绑定网络IP和进程端口

  • 例如,现在有一个服务端进程,绑定地址信息是为了有一个能标识自己在哪一个进程的端口;
  • 一个端口只能被一个进程绑定;
  • 当客户端需要连接该进程只需要拿到端口

对于客户端

  1. 创建套接字
  2. 不推荐绑定地址信息

不推荐绑定地址的原因:

  • 可以让程序在同一机器上启动多个,绑定端口后每个主机就只能启动一个
  • 但是这只是我们没有绑定,而实际操作系统会在调用sendto函数发送数据前自动绑定一个端口

前期准备工作完成后,客户端和服务端就能相互发送消息

在发送消息时,一定是UDP客户端先给服务端发消息,因为服务端是不知道客户端在哪个IP和端口
图示:
在这里插入图片描述

创建套接字

在这里插入图片描述

  • 创建出一个udp类型,就称为udp套接字描述符
  • 创建出一个tcp类型,就称为tcp套接字描述符
  • 套接字描述符本质是文件描述符

函数使用
在这里插入图片描述
所以套接字实质是一块内存

绑定地址信息

在这里插入图片描述

  • sockaddr_un结构体的大小是远大于通用结构体大小,
  • 所以需要用到第三个参数,告诉内核当前结构体的地址信息长度

定义一个通用类型结构体就是为了接收不同的结构体;
结合上图右边的蓝色框起部分理解
在这里插入图片描述

  • 在使用bind函数绑定地址信息时,需要对bind函数的第二个参数进行赋值
  • 也就是对sockaddr_in或sockaddr_un结构体中的变量进行赋值
  • 结构体中有两个普通类型变量sin_family(地址域信息),sin_port(端口)
  • 还有一个结构体变量sin_addr,该结构体内部的变量类型是一个无符号的32位整数,s_addr;要使用inet_addr函数转换

在这里插入图片描述
注意:

  • 端口一定要转化成网络字节序后再负责
  • 结构体第三个参数应传私网ip地址

在这里插入图片描述

接收与发送函数
在这里插入图片描述

服务端代码在这里插入图片描述

客户端代码
在这里插入图片描述

客户端先发送再接收
服务端先接收再发送

udp的发送接收缓冲区

  • 创建套接字后,会在内存中创建一个套接字对应的结构体;
  • 在该结构体中,根据创建套接字的不同类型(udp类型和tcp类型),都会产生两个缓冲区;
  • 一个是发送缓冲区,一个是接收缓冲区(缓冲区在传输层),创建套接字就相当于初始化这两个缓冲区
  • 调用sendto函数发送数据,该数据先会递交给udp的发送缓冲区当中
  • 调用recvfrom函数接收数据,是从接收缓冲区中拿数据

upd是有发送和接收缓冲区,因为udp是整条数据交付的,应用层将数据给udp后,udp就会在发送缓冲区打上udp的包头,递交给网络层的IP协议

  • 程序员基本是与传输层进行交互;
  • 不参与传输层和网络层,与网络层和数据链路层;
  • 这两者是靠net代码进行交互的

公网ip和私网ip

为什么有公网ip和私网ip

  • ipv4版本的ip地址本质是一个无符号的32位整数,约为42亿9千万个不同ip;
  • 但是全球实际的机器不止于此;
  • 所以将其中部分ip取出,让这部分ip不能直接访问互联网;
  • 但是这些ip可以在不同网络中进行附用;
  • 而公网ip可以直接访问互联网;

后面再详述


版权声明:本文为qq_45481606原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。