| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> Linux常用的网络编程函数 -> 正文阅读 |
|
[网络协议]Linux常用的网络编程函数 |
? ? ? ? 由于学习网络编程时间不长,各个网络编程函数,不是很熟悉,也记得不够精确。每次都查半天,经常烦恼于此。索性把它们都记录下来,便于自己记忆以及日后查阅、回顾。 主要介绍:socket、bind、listen、connect、accept、send、sendto、recv、recvfrom、close、shutdown。 1、socket函数在 Linux 下使用 <sys/socket.h> 头文件中 socket() 函数来创建套接字,原型为: int socket(int af, int type, int protocol); 1) af 为地址族(Address Family),也就是 IP 地址类型,常用的有?AF_INET?和?AF_INET6。AF 是“Address Family”的简写,INET是“Inetnet”的简写。AF_INET 表示 IPv4 地址,例如 127.0.0.1;AF_INET6 表示 IPv6 地址,例如?1030::C9B4:FF12:48AA:1A2B。 ? ? ? ? 注意:也可以使用 PF(Protocol Family的简写) 前缀,它和 AF 是一样的。例如,PF_INET 等价于 AF_INET,PF_INET6 等价于 AF_INET6。 2) type 为数据传输方式/套接字类型,常用的有?SOCK_STREAM(流格式套接字/面向连接的套接字)?和?SOCK_DGRAM(数据报套接字/无连接的套接字)。
int tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //IPPROTO_TCP表示TCP协议 这种套接字称为 TCP 套接字。 int udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //IPPROTO_UDP表示UDP协议 这种套接字称为 UDP 套接字。 int tcp_socket = socket(AF_INET, SOCK_STREAM, 0); //创建TCP套接字 int udp_socket = socket(AF_INET, SOCK_DGRAM, 0); //创建UDP套接字 2、bind函数bind() 函数的原型为: int bind(int sock, struct sockaddr *addr, socklen_t addrlen); //Linux int bind(SOCKET sock, const struct sockaddr *addr, int addrlen); //Windows 下面介绍Linux下的bind函数,Windows 与此类似。 ????????sock 为 socket 文件描述符,addr 为 sockaddr 结构体变量的指针,addrlen 为 addr 变量的大小,可由 sizeof() 计算得出。失败返回-1,成功返回非0。
????????这里使用 sockaddr_in 结构体,然后再强制转换为 sockaddr 类型,因为sockaddr_in 结构体赋值比较方便,大小与sockaddr相等。serv_addr.sin_addr.s_addr 也可以赋值,serv_addr.sin_addr.s_addr = htonl(INADDR_ANY),这样就能监听服务器所有IP了。 sockaddr_in 结构体 接下来不妨先看一下 sockaddr_in 结构体,它的成员变量如下:
1) sin_family 和 socket() 的第一个参数的含义相同,取值也要保持一致。 in_addr 结构体 sockaddr_in 的第3个成员是 in_addr 类型的结构体,该结构体只包含一个成员,如下所示:
in_addr_t 在头文件 <netinet/in.h> 中定义,等价于 unsigned long,长度为4个字节。也就是说,s_addr 是一个整数,而IP地址是一个字符串,所以需要?inet_addr() 函数进行转换,例如:
运行结果: ????????为什么要搞这么复杂,结构体中嵌套结构体,而不用 sockaddr_in 的一个成员变量来指明IP地址呢?socket() 函数的第一个参数已经指明了地址类型,为什么在 sockaddr_in 结构体中还要再说明一次呢,这不是啰嗦吗? 为什么使用?sockaddr_in 而不使用?sockaddr bind() 第二个参数的类型为 sockaddr,而代码中却使用 sockaddr_in,然后再强制转换为 sockaddr,这是为什么呢?
下图是 sockaddr 与 sockaddr_in 的对比(括号中的数字表示所占用的字节数):
正是由于通用结构体 sockaddr 使用不便,才针对不同的地址类型定义了不同的结构体。 3、connect() 函数connect() 函数用来建立连接,它的原型为: int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen); //Linux int connect(SOCKET sock, const struct sockaddr *serv_addr, int addrlen); //Windows 各个参数的说明和 bind() 相同,不再赘述。 4、listen() 函数通过 listen() 函数可以让套接字进入被动监听状态,它的原型为:
sock 为需要进入监听状态的套接字,backlog 为请求队列的最大长度,即最大监听数量。 请求队列 当套接字正在处理客户端请求时,如果有新的请求进来,套接字是没法处理的,只能把它放进缓冲区,待当前请求处理完毕后,再从缓冲区中读取出来处理。如果不断有新的请求进来,它们就按照先后顺序在缓冲区中排队,直到缓冲区满。这个缓冲区,就称为请求队列(Request Queue)。 5、accept() 函数当套接字处于监听状态时,可以通过 accept() 函数来接收客户端请求。它的原型为:
它的参数与 listen() 和 connect() 是相同的:sock 为服务器端套接字,addr 为 sockaddr_in 结构体变量,addrlen 为参数 addr 的长度,可由 sizeof() 求得。 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 10:18:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |