当前位置: 首页 > news >正文

【计算机网络】socket编程 几个网络命令

目录

  • 理解端口号
    • 理解源ip地址与目的IP地址
    • 认识端口号
    • 理解端口号与pid关系
  • 理解socket编程
    • 理解网络字节序
    • socket编程接口
      • 常见的API
      • 创建socket套接字
      • bind绑定套接字
      • listen开始监听
      • accept接收请求
      • connect建立连接
      • recvfrom接收数据
      • sendto发送数据
    • sockaddr结构
      • sockaddr底层结构
      • sockaddr_in底层结构
      • in_addr结构
  • 网络命令
    • Ping命令
    • netstat
    • watch
    • pidof
  • 地址转换函数
    • inet_ntoa
    • inet_ntop
    • inet_pton

理解端口号

理解源ip地址与目的IP地址

我们知道ip地址,在网络中可以用来标识主机的唯一性,也就是说我知道你的ip地址,我也就能向你发送数据,但我发送给你的数据,最终是一定要交付给进程的,但交给你哪个进程呢?我应该知道吗?应该,所以就有了端口号,端口号是用来标识主机中的唯一进程的,所以我们在网络中传输数据就只需要拿着目的ip地址和对应进程端口号即可把数据发送到指定进程,所以网络通信又被称为进程间通信,只不过这里是通过网络进行不同主机间通信,不是同一台主机的进程间进行通信。
在这里插入图片描述

认识端口号

端口号(port)是传输层协议的内容。

  • 端口号是一个 2 字节 16 位的整数;
  • 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理;
  • IP 地址 + 端口号能够标识网络上的某一台主机的某一个进程;
  • 一个端口号只能被一个进程占用。

端口号也是有着范围划分的:

  • 0 - 1023: 知名端口号, HTTP, FTP, SSH 等这些广为使用的应用层协议, 他们的
    端口号都是固定的.
  • 1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作
    系统从这个范围分配的

理解端口号与pid关系

我们的进程不是都有进程pid吗,既然有了可以唯一标识一个进程的标志,那为什么我们还要再引入端口号的概念呢???其实是因为进程ID是内核级的,而端口号属于用户级。

  • 进程pid是用来标识正在运行中的进程,进程退出就找不到了。
  • 进程pid每次运行都是变化的,不能保证每次运行的pid都是一样的。
  • 进程 ID 属于系统概念, 技术上也具有唯一性, 确实可以用来标识唯一的一个进程, 但是这样做, 会让系统进程管理和网络强耦合, 实际设计的时候, 并没有选择这样做。

理解socket编程

由于ip+port能够唯一标识某台主机上的唯一一个进程,所以我们把这种ip + port起个名字叫套接字socket,我们只需要源主机的ip+port,目的主机的ip+port就能进行进程间通信了!

理解网络字节序

我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大小端之分,那么怎么定义网络中的数据流的地址呢?在网络中我们是采用的大端字节序存储的,假如A主机向B主机发送数据,A主机是小端存储,B主机是大端存储,A主机发送的数据到达B主机,如果我们不对传输的数据进行统一处理,B主机接收到的数据就可能会是乱码,为了避免这种情况,我们规定进入网络的数据都要转为网络字节序,而TCP/IP协议规定网络字节序是采用的大端存储,低字节放在高地址处。

为使网络程序具有可移植性,使同样的 C 代码在大端和小端计算机上编译后都能正常运
行,可以调用以下库函数做网络字节序和主机字节序的转换。
在这里插入图片描述
这些函数名很好记,h 表示 host,n 表示 network,l 表示 32 位长整数,s 表示 16 位短整数。

  • htonl 表示将 32 位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
  • htons表示将 16 位的短整数从主机字节序转换为网络字节序,例如将端口号地址转换后准备发送。
  • ntohl 表示将 32 位的长整数从网络字节序转换为主机字节序,例如将接收的IP地址转换后准备发送。
  • ntohs表示将 16 位的短整数从网络字节序转换为主机字节序,例如将接收的端口号地址转换后准备发送。

socket编程接口

常见的API

// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address,
socklen_t address_len);
// 开始监听 socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address,socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

创建socket套接字

使用socket创建一个套接字进行通信在这里插入图片描述

  • domain:地址簇,常见的右AF_INET(ipv4)和AF_INET6(ipv6)
  • type:套接字类型,常见的有SOCK_STREAM(TCP)和SOCK_DGRAM(UDP).
  • protocol:协议,通常设置为0,也可指定协议。
  • 返回值:成功返回一个套接字文件描述符,失败返回-1,error被设置。

bind绑定套接字

bind函数可以绑定一个ip地址和端口号
在这里插入图片描述

  • sockfd:套接字文件描述符
  • addr:指向一个sockaddr结构体的结构体指针,该结构体包含了ip地址与端口号等信息,对于IPv4定义在sockaddr_in结构体中,IPv6则在sockaddr_in中定义。
  • addrlen:该结构体对象的大小,通常用sizeof获取。
  • 返回值:成功返回0,错误返回-1,error被设置。

listen开始监听

listen函数用在tcp中用来监听客户端的连接,类似一个老板要不断的监管自己的公司。
在这里插入图片描述

  • sockfd:需要监听的套接字文件描述符
  • backlog:要求连接的最大数量

accept接收请求

accept是一个系统调用,用于在服务器端接受来自客户端的连接请求。
在这里插入图片描述

  • sockfd:套接字文件描述符,用来监听客户端连接请求的套接字,在tcp中可以理解为用来接收外部连接的套接字文件描述符,该函数会返回一个提供IO服务新的套接字文件描述符。
  • addr:输入输出型参数,获取发送方的IP地址端口号等各种信息。
  • addrlen:发放方sockaddr结构体的大小,调用时设置为结构体的总大小,返回时返回实际使用的大小。
  • 返回值是一个新的文件描述符,可以提供IO服务,这个新的这个文件描述符服务器端就可以与客户端进行通信。

connect建立连接

connect用于客户端程序,将其套接字连接到服务器端的套接字,以便进行通信。
在这里插入图片描述

  • sockfd:表示要建立连接的套接字描述符。
  • addr:表示指向目标服务器端套接字的地址结构体的指针。在IPv4中,该结构体类型为struct sockaddr_in,而在IPv6中,该结构体类型为struct sockaddr_in6。
  • addrlen:表示目标服务器端地址结构体的长度。
  • 返回时connect连接成功后会进行bind,返回成功,返回0,失败为-1,错误码被设置

recvfrom接收数据

recvfrom()函数的一个常见用法是在UDP套接字上接收数据报。在这种情况下,可以使用它来接收来自任意源地址的UDP数据报,并获取发送方的地址,以便进行后续处理。
在这里插入图片描述

  • sockfd:指定要接收数据的套接字
  • buf:指定接收数据的缓冲区
  • len:指定要接收数据缓冲区的最大长度
  • flags:指定接收数据的方式(一般设置为0)
  • src_addr:输入输出型参数,获取发送方的IP地址端口号等各种信息。
  • addrlen:发放方sockaddr结构体的大小,调用时设置为结构体的总大小,返回时返回实际使用的大小。

sendto发送数据

sendto函数将数据报发送到指定的目的地址。
在这里插入图片描述

  • sockfd:指定要发送数据的套接字文件描述符。
  • buf:指定发送数据的缓冲区。
  • len:指定要发送数据的长度。
  • flags:指定发送数据的方式(一般设置为0)
  • dest_addr:输入输出型参数,指向目的地址的的结构体指针,可以是IP地址和端口号。
  • addrlen:目的地址sockaddr结构体的大小。
  • 成功则返回发送的字节数,失败返回-1,error被设置。

sockaddr结构

由于各种网络协议的格式并不相同,所以就有了sockaddr结构来,在使用sockaddr结构时底层上派生了其他相对应的具体结构,sockaddr只是作为基类来使用,例如就派生的结构体有:struct sockaddr_in,struct sockaddr_un。这其实是利用了多态的思想实现的!!!
在这里插入图片描述

  • IPv4 和 IPv6 的地址格式定义在 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 结构体指针做为参数。

sockaddr底层结构

struct sockaddr
{__SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */char sa_data[14];		/* Address data.  */
};

sockaddr_in底层结构

/* Structure describing an Internet socket address.  */
struct sockaddr_in
{__SOCKADDR_COMMON (sin_);in_port_t sin_port;			/* Port number.  */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)];
};

in_addr结构

/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr
{in_addr_t s_addr;
};

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

网络命令

Ping命令

ping www.baidu.com可以查看自己的网络是否正常运行
在这里插入图片描述
ping -c 5 www.baidu.com可以查看5条后停止
在这里插入图片描述

netstat

netstat用来查看网络状态

  • n 拒绝显示别名, 能显示数字的全部转化成数字
  • l 仅列出有在 Listen (监听) 的服務状态
  • p 显示建立相关链接的程序名
  • t (tcp)仅显示 tcp 相关选项
  • u (udp)仅显示 udp 相关选项
  • a (all)显示所有选项, 默认不显示 LISTEN 相关

可以查看自己启动的网络服务状态
在这里插入图片描述
普通用户默认是看不到别的pid等信息的,只有超级用户全部都能看到。

watch

watch -n 1 netstat -uap 每隔一秒执行一次netstat -uap命令
在这里插入图片描述

pidof

pidof用来查看服务器的进程id时非常方便

pidof + 进程名
在这里插入图片描述
pidof UdpServerMain | xargs kill -9 xargs让我们从标准输入中读转为在从命令行参数中去读
在这里插入图片描述

地址转换函数

inet_ntoa

在这里插入图片描述
inet_ntoa可以把四字节地址转换为字符串类型。
但是在多线程使用inet_ntoa时可能不是线程安全的(因为这个函数转换时会自己维护一个类似缓冲区的地方,类似文件fopen的返回值),一般我们不会使用它,而使用inet_ntop。

inet_ntop

在这里插入图片描述
inet_ntop可以把四字节地址转换为字符串类型。
但是这个缓冲区可以由我们自己来维护了,更加方便。

  • af:网络协议,一般传AF_INET
  • src:传入四字节地址
  • dst:目的缓冲区
  • size:缓冲区大小

inet_pton

在这里插入图片描述
inet_pton是把字符串类型转换为四字节ip地址

  • af:网络协议,一般传AF_INET
  • src:传入缓冲区地址
  • dst:转换的目的位置

这里的p:process, n: net

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • LeetCode 每日一题 2024/9/2-2024/9/8
  • 数据结构中抽象数据类型如何实现?
  • python实现RPC算法
  • Android 优雅封装Glide
  • Iceberg与SparkSQL整合DDL操作
  • el-table使用type=“expand”根据数据条件隐藏展开按钮
  • Ceph集群维护相关操作
  • 图特征工程实践指南:从节点中心性到全局拓扑的多尺度特征提取
  • 《系统架构设计师教程(第2版)》第17章-通信系统架构设计理论与实践-02-广域网网络架构
  • 解决MongoDB创建用户报错command createUser requires authentication
  • 设计模式-行为型模式-迭代器模式
  • 【秋招笔试】9.07美团秋招改编题(研发岗)
  • 【2024高教社杯国赛A题】数学建模国赛建模过程+完整代码论文全解全析
  • 纳米材料咋设计?蛋白质模块咋用?看这里就知道啦!
  • 数学建模_缺失值处理_拉格朗日、牛顿插值(全)
  • JS 中的深拷贝与浅拷贝
  • Docker容器管理
  • ES6系列(二)变量的解构赋值
  • Laravel 实践之路: 数据库迁移与数据填充
  • mysql 5.6 原生Online DDL解析
  • python 装饰器(一)
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • SpiderData 2019年2月23日 DApp数据排行榜
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • ViewService——一种保证客户端与服务端同步的方法
  • 给Prometheus造假数据的方法
  • 京东美团研发面经
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 转载:[译] 内容加速黑科技趣谈
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #Linux(make工具和makefile文件以及makefile语法)
  • #window11设置系统变量#
  • #进阶:轻量级ORM框架Dapper的使用教程与原理详解
  • (12)Linux 常见的三种进程状态
  • (35)远程识别(又称无人机识别)(二)
  • (done) 两个矩阵 “相似” 是什么意思?
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (二)延时任务篇——通过redis的key监听,实现延迟任务实战
  • (七)Knockout 创建自定义绑定
  • (十八)SpringBoot之发送QQ邮件
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)setTimeout 和 setInterval 的区别
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .Net IE10 _doPostBack 未定义
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET MVC之AOP
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 回调、接口回调、 委托