ip+端口=套接字,现在所说的socket编程就是套接字编程
编程流程
对于网络编程要从客户端和服务端来看,在网络通信前,双方都要做准备工作:
对于服务端
1.创建套接字
2.绑定地址信息绑定地址信息是绑定网络IP和进程端口
- 例如,现在有一个服务端进程,绑定地址信息是为了有一个能标识自己在哪一个进程的端口;
- 一个端口只能被一个进程绑定;
- 当客户端需要连接该进程只需要拿到端口
对于客户端
- 创建套接字
- 不推荐绑定地址信息
不推荐绑定地址的原因:
- 可以让程序在同一机器上启动多个,绑定端口后每个主机就只能启动一个
- 但是这只是我们没有绑定,而实际操作系统会在调用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版权协议,转载请附上原文出处链接和本声明。