网络编程---TCP/UDP套接字编程原理

2023-11-18

本篇介绍的是Linux下的网络编程,故有些接口是不适用于Windows的,但是具体概念和实现方法是大体一致的
本篇重在讲解原理,具体实现请戳这里->UDP套接字编程实现

介绍

  • 网络编程套接字(socket)也是进程间通信的一种方式,但是不同于管道,消息队列,共享内存的是socket不仅可以实现本机内不同进程间的通信,也可以实现网络中两台不同主机间的进程通信。
  • socket相当于是一个文件描述符,我们将数据写入socket中,再发到目标主机,目标主机接收socket,再从socket中读取数据,至此便实现了网络中两台主机间的数据传输,即进程通信。

  • 举个栗子:如果是两个人进行通信的话,首先要知道彼此的电话号码,而且要明确两个人谈论的事项,即使是闲聊也算生活事项的一种。网络中的两台主机进行通信也是如此,电话号码即彼此的ip地址,谈论的事项即彼此主机上确定的一个端口号

解释ip地址+端口号

网络编程套接字可以看做是ip地址+端口号,ip地址为了明确网络中唯一一台主机,而端口号确定了这台主机上的唯一一个进程,因为一个端口号只能被一个进程占用,而且只有网络进程才有端口号。

IP地址

IP协议有两个版本,IPv4和ipv6,现在普遍用的都是IPv4,IPv6是为了解决现有的IP地址可能不够的情况,但还没有普及开来。我们接下来使用的全是IPv4协议。

  • IP地址是在IP协议中,用来标识网络中不同主机的地址;
  • 对于IPv4来说,IP地址是一个4字节,32位的整数;
  • 我们通常也使用“点分十进制”的字符串标识IP地址,例如192.168.0.1;用点分割的每一个数字表示一个字节,范围是0~255。
端口号

端口号是传输层协议的内容

  • 端口号是一个2字节16位的整数;
  • IP地址+端口号用来标识网络中某一台主机上的唯一一个进程;
  • 一个端口号只能被一个进程占用,只有网络进程才有端口号。
网络字节序

大家可能刚看到这个觉得有点陌生,我来为大家解释一下。

  我们都知道我们的计算机存储数据时是分大端和小端的,而且主机和主机之间的存储模式是不固定的,也就是没有统一的标准,即如果你是大端的模式,而对方却是小端的模式,你们在交换数据时就会发生错误,所以为了避免差异化,TCP/IP协议规定,网络数据流应采用大端字节序,即低地址存放数据的高字节。

  无论当前主机是大端机还是小端机,是发送端还是接收端,都要按照这个TCP/IP协议规定的网络字节序来处理数据,如果当前发送主机是小端。则需要先将数据转成大端;否则就忽略,直接发送即可;

  调用以下库函数可以实现网络字节序和主机字节序之间的转换

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
//将32位的长整数从主机字节序转换位网络字节序
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
  • h表示host,n表示network,l表示32位长整数,s表示16位短整数。
  • 如果主机是小端字节序,则函数内部会转换成大端,如果主机是大端,则函数内部不做转换

socket编程接口


socket常用API

//创建 socket 文件描述符(TCP/UDP, 客户端 + 服务器)
//domain: 一个地址描述。目前仅支持AF_INET,,代表sockaddr_in结构体
//type: 服务类型,UDP为SOCK_DGRAM, TCP为SOCK_STREAM
//protocol: 套接口所用的协议。如调用者不想指定,可用0指定,表示缺省。
int socket (int domain, int type, int protocol);

//绑定端口号(TCP/UDP, 服务器)
//客户端不用该接口,而且对于服务器而言,端口号必须是众所周知,不可修改的
int band (int socket, const struct sockaddr *address, socklen_t address_len);

//开始监听 socket(TCP, 服务器)
//作用:将套接字由新创建状态设置为监听状态,即监听是否有客户端请求连接
//backlog: 监听队列,不要设置的太大,5~10就差不多了,避免浪费资源
int listen(int socket, int backlog);

//接受请求(TCP, 服务器)
//与客户端连接成功后,返回一个用于服务的文件描述符,也可以当做是客户端的文件描述符,用于写入和读取数据
//否则进行阻塞式等待,失败返回-1
int accept (int socket, struct sockaddr* address, socklen_t* address_len);

//建立连接(TCP, 客户端)
int connect (int socket,const struct sockaddr* address, socklen_t addrlen);

sockaddr结构

socket常见API中经常出现sockaddr*,下面就为大家详解该结构体的作用以及用法 .

  • sockaddr用于存储参与套接字通信的一个计算机上的IP协议地址。为了统一地址结构的表示方法 ,统一接口函数,使得不同的地址结构可以被bind()、connect()、recvfrom()、sendto()等函数调用。

  • 但一般的编程中并不直接对此数据结构进行操作,而使用另一个与之等价的数据结构sockaddr_in。实际填充字段的每一部分则遵循sockaddr_in数据结构,两者大小都是16字节,所以二者之间可以进行切换。

这里写图片描述

  • sockaddr
struct sockaddr {
  unsigned short sa_family; //:是2字节的地址家族,一般都是“AF_xxx”的形式,通常用AF_INET
  char sa_data[14]; //14字节的地址数据
  }
  • sockaddr_in
struct sockaddr_in {
  short int sin_family; /* Address family */
  unsigned short int sin_port; /* Port number */
  struct in_addr sin_addr; /* Internet address */
  unsigned char sin_zero[8]; /* Same size as struct sockaddr */
  };
  //sin_family:指代协议族,在socket编程中只能是AF_INET
  //sin_port:存储端口号(使用网络字节顺序)
  //sin_addr:存储IP地址,使用in_addr这个数据结构
  //sin_zero:是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。
  • sockaddr_in 中的 in_addr
typedef struct in_addr {
  union {
  struct{ unsigned char s_b1,s_b2, s_b3,s_b4;} S_un_b;
  struct{ unsigned short s_w1, s_w2;} S_un_w;
  unsigned long S_addr;
  } S_un;
  } IN_ADDR;

阐述下in_addr的含义,很显然它是一个存储ip地址的共用体有三种表达方式:

第一种用四个字节来表示IP地址的四个数字;
第二种用两个双字节来表示IP地址;
第三种用一个长整型来表示IP地址。

  给in_addr赋值的一种最简单方法是使用inet_addr函数,它可以把一个代表IP地址的字符串赋值转换为in_addr类型,如addrto.sin_addr.s_addr=inet_addr(“192.168.0.2”);
  其反函数是inet_ntoa,可以把一个in_addr类型转换为一个字符串。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

网络编程---TCP/UDP套接字编程原理 的相关文章

  • Linux shell 命令逐块读取/打印文件

    是否有一个标准的 Linux 命令可以用来逐块读取文件 例如 我有一个大小为 6kB 的文件 我想读取 打印第一个 1kB 然后是第二个 1kB 看来猫 头 尾在这种情况下不起作用 非常感谢 你可以这样做read n在循环中 while r
  • 如何查找或计算Linux进程的页表大小和其他内核占用?

    我怎样才能知道 Linux 进程页表有多大 以及任何其他可变大小的进程统计 如果您真的对页表感兴趣 请执行以下操作 cat proc meminfo grep PageTables PageTables 24496 kB
  • bash双括号问题

    我对 bash 脚本非常陌生 在使用双括号时遇到了问题 我似乎无法让它们在 Ubuntu Server 11 10 中工作 我的下面的脚本位于 if test sh 中 bin bash if 14 14 then echo FOO fi
  • 是否可以找到哪个用户位于 localhost TCP 连接的另一端?

    这是一个编程问题 但它是 Linux Unix 特定的 如果我从本地主机获得 TCP 连接 是否有一种简单的方法可以告诉哪个用户在 C 程序内建立了连接而无需 shell 我知道这对于 Unix 域套接字来说并不太难 我已经知道远程 IP
  • 如何删除树莓派的相机预览

    我在我的 raspberryPi 上安装了 SimpleCv 并安装了用于使用相机板的驱动程序 uv4l 驱动程序 现在我想使用它 当我在 simpleCV shell Camera 0 getImage save foo jpg 上键入时
  • 为什么使用Python的os模块方法而不是直接执行shell命令?

    我试图了解使用Python的库函数执行特定于操作系统的任务 例如创建文件 目录 更改文件属性等 背后的动机是什么 而不是仅仅通过执行这些命令os system or subprocess call 例如 我为什么要使用os chmod而不是
  • 如何使用libaudit?

    我试图了解如何使用 libaudit 我想接收有关使用 C C 的用户操作的事件 我不明白如何设置规则 以及如何获取有关用户操作的信息 例如 我想获取用户创建目录时的信息 int audit fd audit open struct aud
  • Linux TCP服务器:在接受连接之前读取客户端的IP地址

    Related C Winsock API如何在接受连接之前获取连接客户端IP https stackoverflow com questions 716209 c winsock api how to get connecting cli
  • 在中断时获取 current->pid

    我正在Linux调度程序上写一些东西 我需要知道在我的中断到来之前哪个进程正在运行 当前的结构可用吗 如果我在中断处理程序中执行 current gt pid 我是否可以获得我中断的进程的 pid 你可以 current gt pid存在并
  • 如何阅读shell命令的源代码?

    我想阅读编写linux命令的实际源代码 我已经获得了一些使用它们的经验 现在我认为是时候与我的机器进行更深层次的交互了 我在这里找到了一些命令http directory fsf org wiki GNU http directory fs
  • 通过 SSH 将变量传递给远程脚本

    我正在通过 SSH 从本地服务器在远程服务器上运行脚本 首先使用 SCP 复制该脚本 然后在传递一些参数时调用该脚本 如下所示 scp path to script server example org another path ssh s
  • 远程linux服务器到远程linux服务器大型稀疏文件复制 - 如何?

    我有两台 CentOS 5 4 服务器 每台服务器上都安装了 VMware Server 假设我始终对 vmware 虚拟机使用稀疏文件 将虚拟机文件从一台服务器复制到另一台服务器的最可靠 最快速的方法是什么 虚拟机的文件复制起来很痛苦 因
  • Xenomai 中的周期性线程实时失败

    我正在创建一个周期性线程 它在模拟输出上输出方波信号 我正在使用 Xenomai API 中的 Posix Skin 和 Analogy 我使用示波器测试了代码的实时性能 并查看了方波信号 频率为 1kHz 的延迟 我应该实现 250us
  • Windows 与 Linux 文本文件读取

    问题是 我最近从 Windows 切换到 Ubuntu 我的一些用于分析数据文件的 python 脚本给了我错误 我不确定如何正确解决 我当前仪器的数据文件输出如下 Header 有关仪器等的各种信息 Data 状态 代码 温度 字段等 0
  • 访问 AWS 上的 Tensorboard

    我正在尝试访问 AWS 上的 Tensorboard 这是我的设置 张量板 tensorboard host 0 0 0 0 logdir train 在端口 6006 上启动 TensorBoard b 39 您可以导航到http 172
  • 无法分配请求的地址 - 可能的原因?

    我有一个由主服务器和分布式从服务器组成的程序 从属服务器向服务器发送状态更新 如果服务器在固定时间内没有收到特定从属服务器的消息 则会将该从属服务器标记为关闭 这种情况一直在发生 通过检查日志 我发现从站只能向服务器发送一个状态更新 然后永
  • Linux、ARM:为什么仅当启动时存在 I2C GPIO 扩展器时才创建 gpiochip

    在 imx6sx 硬件平台 NXP 嵌入式 ARM 上使用 Linux 3 14 52 问题是设备树中指定的 PCF8575 I2C GPIO 扩展器不会实例化为 sys class gpio 结构中的设备 除非它们在内核启动期间存在 这些
  • 为什么 UDP 服务器中只有一个套接字?

    我正在准备考试 发现了这个问题 典型的 UDP 服务器可以使用单个套接字来实现 解释一下为什么 对于 TCP 驱动的服务器 我发现创建了两个套接字 一个用于所有客户端访问服务器 另一个用于每个客户端的特定 套接字 用于服务器和客户端之间的进
  • 错误:NVIDIA-SMI 失败,因为无法与 NVIDIA 驱动程序通信

    NVIDIA SMI 抛出此错误 NVIDIA SMI 失败 因为无法与 NVIDIA 通信 司机 确保安装了最新的 NVIDIA 驱动程序并且 跑步 我清除了 NVIDIA 并按照提到的步骤重新安装了它here https askubun
  • 在 shell 脚本中查找和替换

    是否可以使用 shell 在文件中搜索然后替换值 当我安装服务时 我希望能够在配置文件中搜索变量 然后在该值中替换 插入我自己的设置 当然 您可以使用 sed 或 awk 来完成此操作 sed 示例 sed i s Andrew James

随机推荐

  • eNSP实验:DHCP&&安全区域&&安全策略&&静态路由

    解题思路 1 先给各个接口以及server1服务器配置好地址 2 连接Cloud云 利用物理 web 防火墙 方便操作 只用命令行的情况下可以不用这个方法 3 利用DHCP给各个方向接口的PC自动分配好地址 4 利用静态路由的方法 将两个防
  • VimFoundation

    模式 vim 分为两种模式 1 命令模式 2 编辑模式 命令模式 i 进入编辑模式 w 保存 q 退出 强制 syntax on 打开语法高亮 set number 显示行号 cc 剪切当前行 pp 粘贴到当前行 u 撤销3武器3 yy 复
  • 开源大模型资料总结

    基本只关注开源大模型资料 非开源就不关注了 意义也不大 基座大模型 LLaMA 7 13 33 65B 1 4T token LLaMA及其子孙模型概述 知乎 GLM 6 130B ChatGLM基座 GLM General Languag
  • C++基础知识 - stack容器

    stack容器 stack是堆栈容器 是一种 先进后出 的容器 stack是基于deque容器而实现的容器 include lt stack gt stack对象的默认构造 stack采用模板类实现 stack对象的默认构造形式 stack
  • 金三银四必备,全面总结 Kotlin 面试知识点

    作者 彭旭锐 前言 在 Android 面试中很重视基础知识的考察 其中语言基础主要包括 Java Kotlin C C 三种编程语言 在小彭面试的经验中 发现很多同学的 Kotlin 语言能力只是停留在一些非常入门的语法使用上 在这篇文章
  • 如何让ChatGPT写情书(三步走)

    近年来 人工智能技术的迅猛发展给我们生活带来了许多便利和惊喜 而动人的情书文学也逐渐成为ChatGPT技术的应用领域之一 ChatGPT模型是一种递归神经网络 可以在大量数据的基础上为用户生成语言内容 使用GPT来写情书 相比以前的纯手工撰
  • python详细安装教程(配置环境变量)

    python安装教程 配置环境变量 人生苦短 我用python 直接在官网下载安装包 msi文件进行安装 https www python org downloads windows 下载python 注意 浏览器左下角下载 点击后 会自动
  • conda和pip 安装python依赖包区别和使用技巧

    引言 Conda 作为一种跨平台的包和虚拟环境管理器 使用的时候功能与pip类似 安装python依赖包的时候经常将两种方法混合使用 但一直没有进行具体区分其差别 重新安装python依赖包的时候出现各种不兼容的bug 经历一天烦躁的安装
  • 你不知道的 script 标签的 defer 与 async 属性

    我持续组织了近一年的源码共读活动 感兴趣的可以 点此扫码加我微信 ruochuan12 参与 每周大家一起学习200行左右的源码 共同进步 同时极力推荐订阅我写的 学习源码整体架构系列 包含20余篇源码文章 历史面试系列 另外 目前建有江西
  • 4G路由器设置

    总共分四步如下图所示 1 用网线连接电脑 2 给路由器上电 3 设置电脑网络 如图打开电脑网络和共享数据中心选中本地连接双击 弹出如下图所示弹框选择图中ipv4双击 根据下面图片配置ip地址 4 浏览器上输入地址访问路由器进行配置 第一步
  • CV 经典主干网络 (Backbone) 系列: CSP-Darknet53

    CSP Darknet53 0 引言 1 网络结构图 1 1 输入部分 1 2 CSP部分结构 1 3 输出部分 2 代码实现 2 1 代码整体实现 2 2 代码各个阶段实现 3 代码测试 4 结论 0 引言 CSP Darknet53无论
  • Halcon实战记录之二《判断两个直线或者矩形是否相交》

    项目中使用到需要判断两个矩形是否相交 由于我使用Halcon不久 对其算子还不熟悉 不知道是否有现成的算子可以直接实现 如果有 还请各位朋友给留言指出 先谢谢了 我这里用了如下的方法 1 如果两个矩形相交 那么它们中的线段一定会有相交的 我
  • LeetCode 687. 最长同值路径

    题目链接 https leetcode cn problems longest univalue path C 代码如下 Definition for a binary tree node struct TreeNode int val T
  • 优惠券的设计分享

    优惠券是一种常见的促销手段 在形式上给予消费者心理一定的折扣 然后促成订单 本文主要分享关于优惠券的设计 一 引子 促销活动的目的按对象可分为对用户 对产品 对公司 其中对用户的促销目的又可分为三种 拉新 促活 留存 优惠券作为一种常见的促
  • 前端基础知识与常见面试题(九)

    描述 现有n种砝码 重量互不相等 分别为 m1 m2 m3 mn 每种砝码对应的数量为 x1 x2 x3 xn 现在要用这些砝码去称物体的重量 放在同一侧 问能称出多少种不同的重量 注 称重重量包括 0 输入描述 对于每组测试数据 第一行
  • 逆向某联盟RSA登录

    目录 1 抓包分析 2 逆向 1 抓包分析 经典抓包套路 发现载荷password的参数进行了加密 还是如此之长 那就可以猜测是RSA加密了 点击启动器 找到login位置 然后搜索password 发现果然是RSA加密 人家还贴切的给了注
  • 零基础入门STM32编程——GPIO(五)

    系列教程链接 HAL库编程点灯篇https blog csdn net oHaoEr article details 122999523 一 GPIO简介 1 1 概述 GPIO 通用输入输出端口 即芯片的IO管脚 STM32F103系列中
  • 深度学习训练之optimizer优化器(BGD、SGD、MBGD、SGDM、NAG、AdaGrad、AdaDelta、Adam)的最全系统详解

    文章目录 1 BGD 批量梯度下降 2 SGD 随机梯度下降 2 1 SGD导致的Zigzag现象 3 MBGD 小批量梯度下降 3 1 BGD SGD MBGD的比较 4 SGDM 5 NAG 6 AdaGrad Adaptive Gra
  • EndNote在word中进行文献引用的插入时,没有出现编号问题

    转载链接 https blog csdn net qq 32120957 article details 83547621 EndNote 是一个著名的参考文献管理软件 用来创建个人参考文献库 并且可以加入文本 图像 表格和方程式等内容及链
  • 网络编程---TCP/UDP套接字编程原理

    本篇介绍的是Linux下的网络编程 故有些接口是不适用于Windows的 但是具体概念和实现方法是大体一致的 本篇重在讲解原理 具体实现请戳这里 gt UDP套接字编程实现 介绍 网络编程套接字 socket 也是进程间通信的一种方式 但是