【网络编程】详解UDP/TCP套接字的创建流程

news2024/11/26 10:23:15


 目录

一、网络编程套接字

1、一些概念

1.1源IP地址和目的IP地址

1.2端口号port

1.3TCP和UDP的性质

1.4网络字节序、IP地址类型转换、数据接收与发送函数、popen函数

2、UDP套接字

2.1UDP服务器创建流程

2.2UDP客户端创建流程

2.3创建socket套接字

2.4绑定套接字对应的IP地址、端口号

2.5客户端、服务器数据的接收与发送

3、TCP套接字

3.1TCP服务器创建流程

3.2TCP客户端创建流程

3.3创建socket套接字

3.4绑定套接字对应的IP地址、端口号

3.5服务器设置socket为监听状态

3.6服务器获取客户端连接请求

3.7客户端发起连接请求


UDP/TCP客户端、服务器代码可参考本人gitee

一、网络编程套接字

1、一些概念

1.1源IP地址和目的IP地址

源IP地址:发送主机的IP地址。

目的IP地址:接收主机的IP地址。

1.2端口号port

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

1、端口号是一个2字节的整数;

2、端口号用于告诉操作系统,当前这个数据要交给哪一个进程处理;

3、IPA+portA就能标定发送的主机中的进程,IPB+portB就能标定接收数据的主机中的进程,实现进程间通信。(IP+port就是套接字

4、一个端口号只能绑定一个进程,一个进程可以绑定多个端口号。

        既然网络通信的双方本质都是进程,为什么不直接使用pid来标定网络通信双方通信进程的唯一性,而是使用端口号呢?1、解耦2、例如客户端需要找到服务器进程,因为进程每次创建销毁pid是会变的,而网络编程弄了个端口号,直接写死了是哪个进程,这样每次都能找到。

        那么怎么找呢?操作系统内部维护了一张哈希表,key是端口号,value是进程PCB的地址。

1.3TCP和UDP的性质

UDP:

传输层协议、无连接、不可靠传输、面向数据报

TCP:

传输层协议、有连接、可靠传输、面向字节流

1.4网络字节序、IP地址类型转换、数据接收与发送函数、popen函数

1、TCP/IP协议规定,网络数据流应采用大端字节序,即低地址存高字节,不管这台主机是大端机还是小端机

2、如果当前发送主机是小端, 就需要先将数据转成大端; 反之直接发送即可(不管本机是大端还是小端,最好都转换一下,便于日后跨平台、跨主机的需要)

3、发送主机和接收主机都是按照低地址到高地址发送/接收数据;

可以使用以下库函数做网络字节序和主机字节序的转换:

BYTEORDER(3)
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。

可以使用以下库函数对ip地址进行转换:

INET(3) 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);//将字符串转uint32_t的同时转为网络字节序
in_addr_t inet_network(const char *cp);
char *inet_ntoa(struct in_addr in);//将32位IPv4地址(in_addr结构体)转换成点分十进制字符串形式的IP地址
struct in_addr inet_makeaddr(int net, int host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);

popen函数==pipe+fork+exec*

POPEN(3)    
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);

用途:函数popen()用于打开一个用于读取或写入的管道,以便与另一个进程进行通信。

参数:

  • command:要执行的命令
  • type:打开管道的模式,可以是“r”(读)或“w”(写)。

返回值:返回一个指向FILE结构的指针,可以像使用普通文件一样使用它来读取或写入管道。如果打开管道失败,返回NULL

2、UDP套接字

UDP套接字种类及接口

1、网络套接字2、原始套接字3、unix域间套接字

2.1UDP服务器创建流程

1、创建套接字(sockrt)

2、绑定端口号和IP地址。这个端口号是写死的,这个IP地址0.0.0.0或htonl(INADDR_ANY)两种写法(bind)

3、发送、接收数据,对数据进行处理(recvfrom/sendto)

2.2UDP客户端创建流程

1、创建套接字(sockrt)

2、客户端需要bind,但是客户端的绑定不需要我们自己写,操作系统会去绑定;(无需程序员bind)

3、发送、接收数据,对数据进行处理(recvfrom/sendto)

相关指令及函数:

ifconfig 显示网络设备信息,找到127.0.0.1本地回环地址
ps axj | grep udpServer过滤出当前的udpServer进程
netstat -nuap//n:能显示数字的现实成数字;u:udp;a:all;p:进程
sudo netstat -nuap//n:以数字形式显示地址和端口号,不进行反向解析,a:all,u::udp,p:process ID/name,
sudo netstat -altp//l::listen,t:tcp
recvfrom
sendto
close
bzero

2.3创建socket套接字

SOCKET(2)      
#include <sys/types.h> 
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

用途:创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)

参数:

  • domain:指定套接字的协议族。常见的协议族有AF_INET(IPv4网络通信)、AF_UNIX/AF_LOCAL(本地通信)
  • type:指定套接字的类型。常见的类型有SOCK_STREAM(流套接字)和SOCK_DGRAM(数据报套接字)。
  • protocol:给0就行。【指定套接字使用的协议。常见的协议有IPPROTO_TCP(TCP协议)和IPPROTO_UDP(UDP协议)】

调用成功返回值:返回一个文件描述符;

调用失败返回值:返回-1,设置error变量以指示原因。

2.4绑定套接字对应的IP地址、端口号

BIND(2)        
#include <sys/types.h>       
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

用途:将一个套接字(socket)与一个特定的IP地址和端口号绑定

参数:

  • sockfd:套接字描述符,即要绑定的套接字。
  • addr:一个指向 sockaddr 结构体的指针,该结构体包含了IP地址和端口号等信息。
  • addrlen:sockaddr 结构体的大小

返回值:返回值为0,则表示函数执行成功;否则,返回值为-1,表示函数执行失败。在函数执行失败时,可以通过 errno 全局变量获取错误码,以便进行错误处理。

2.5客户端、服务器数据的接收与发送

UDP 套接字是无连接协议,必须使用recvfrom函数接收数据,sendto函数发送数据:

RECV(2)
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

用途:从已连接的socket中接收数据,并将数据存储到指定的缓冲区中。

参数:

  • sockfd:已经建立好连接的socket。
  • buf:指向接收数据存放的缓冲区。
  • len:缓冲区长度。
  • flags:一般为0,阻塞式读取。
  • src_addr:(输出参数)返回发送方的地址信息。
  • addrlen:(输出参数)地址信息的长度。

调用成功返回值:函数成功接收到数据时,它会返回接收到的字节数

调用失败返回值:发生错误,则返回-1,并设置errno变量以指示错误类型。

SEND(2)      
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
          	const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

用途:该函数用于将数据报发送到指定的目的地。

参数:

  • sockfd:表示要发送数据的套接字文件描述符。
  • buf:指向要发送的数据缓冲区。
  • len:表示要发送的数据长度。
  • flags:表示发送数据的选项,常用的选项有MSG_DONTWAIT和MSG_NOSIGNAL。
  • dest_addr:(输入参数)指向目的地址的结构体指针,表示要发给谁。
  • addrlen:(输入参数)表示目的地址结构体的长度。

返回值:成功发送的字节数,如果返回值为-1,则表示发送失败,具体错误码可以通过errno变量获取。

3、TCP套接字

3.1TCP服务器创建流程

1、创建监听套接字(socket)

2、绑定端口号和IP地址。这个端口号是写死的,这个IP地址0.0.0.0或htonl(INADDR_ANY)两种写法(bind)

3、服务器设置socket为监听状态(listen)

4、服务器获取客户端连接请求(accept)

5、文件操作进行读写通信(read/write)

3.2TCP客户端创建流程

1、创建套接字(socket)

2、客户端需要bind,但是客户端的绑定不需要我们自己写,操作系统会去绑定;(无需程序员bind)

3、客户端发起连接请求(connect)

4、文件操作进行读写通信(read/write)

3.3创建socket套接字

同UDP创建套接字的方法,只不过在传参时UDP传入SOCK_DGRAM(数据报),而TCP传入SOCK_STREAM(字节流)

_sockfd=socket(AF_INET,SOCK_DGRAM,0);//UDP网络通信+数据报
_listenfd=socket(AF_INET,SOCK_STREAM,0);//TCP网络通信+字节流

3.4绑定套接字对应的IP地址、端口号

同UDP。

3.5服务器设置socket为监听状态

因为TCP是有连接的协议,需要使用listen函数将一个套接字设置为监听状态。

LISTEN(2)   
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);

用途: listen函数用于将一个套接字(socket)设置为监听模式,以便接受客户端的连接请求。

参数:

  • sockfd:需要设置为监听模式的套接字描述符
  • backlog:指定等待连接队列的最大长度,即同时能够处理的客户端连接请求的最大数量,超过这个数量的连接请求将被拒绝

调用成功返回值:成功返回0

调用失败返回值:失败返回-1,并设置errno变量以指示错误类型。

3.6服务器获取客户端连接请求

ACCEPT(2) 
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

用途:accept函数用于从处于监听状态的套接字队列中取出一个已经完成了三次握手的连接请求,并创建一个新的套接字用于与客户端进行通信。

参数:

  • sockfd:处于监听状态的套接字描述符
  • addr:指向一个sockaddr结构体的指针,用于存储客户端的地址信息
  • addrlen:addr结构体的长度,需要在调用前初始化为sizeof(struct sockaddr)

调用成功返回值:返回一个新的套接字描述符,用于与客户端进行通信,这个新的套接字描述符是唯一的,只能用于与这个客户端进行通信。

调用失败返回值:失败返回-1,并设置errno变量以指示错误类型。

3.7客户端发起连接请求

CONNECT(2)   
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

用途:connect函数用于客户端与服务器建立连接,自动帮客户端的套接字与其ip、port进行绑定。

参数:

  • sockfd:需要连接的套接字描述符。
  • addr:指向目标地址的指针,包括目标计算机的IP地址和端口号。
  • addrlen:addr结构体的长度,需要在调用前初始化为sizeof(struct sockaddr)

调用成功返回值:返回0

调用失败返回值:失败返回-1,并设置errno变量以指示错误类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/538772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

快速找出PATH 路径下重复的命令程序文件

RT&#xff0c;就是想找出命名冲突的可执行文件。日积月累的&#xff0c;PATH 环境变量里乱七八糟堆了一堆东西&#xff0c;很可能想叫一个命令出来&#xff0c;结果实际执行的是另一个地方的程序。 Python 脚本 import ospath os.environ[PATH] folders path.split(;) fil…

理解HttpSession

什么是session 在我刚刚从事后端开发的时候&#xff0c;有一个问题困扰了我很久。 就有个玩意叫session。 PostMapping("login")public Result login(RequestParam("id") String id,RequestParam("password") String password, HttpSession se…

哈希及模拟实现

文章目录 哈希1. 哈希相关概念1.1 哈希概念1.2 哈希冲突1.3 哈希函数1.4 哈希冲突解决1.4.1 闭散列/开放定址法(1)线性探测(2) 二次探测 1.4.2 开散列/哈希桶 2. 开放定址法的实现2.1 结构2.2 插入Insert2.2.1 传统写法2.2.2 现代写法 2.3 查找Find2.4 删除Erase2.5 整体代码 3…

springcloud基于web的智慧养老平台

系统分析 可行性分析 在开发系统之前要进行系统可行性分析&#xff0c;目的是在用最简单的方法去解决最大的问题&#xff0c;程序一旦开发出来满足了用户的需要&#xff0c;所带来的利益也很多。下面我们将从技术、操作、经济等方面来选择这个系统最终是否开发。 1、技术可行…

一图看懂 dateutil 模块:Python datetime 模块的扩展,资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 dateutil 模块&#xff1a;Python datetime 模块的扩展&#xff0c;资料整理笔记&#xff08;大全&#xff09; &#x1f9ca;摘要&#x1f9ca;模块图&#x1f9ca;类关系…

005、数据库结构

数据库结构 1、数据库集簇逻辑结构2、对象标识符3、数据库集簇物理结构4、其它目录结构表空间物理文件位置1、数据库集簇逻辑结构 • 数据库集簇逻辑结构 数据库 : 把数据逻辑分开存放。 对象是放在数据库当中。表空间: 把数据从逻辑或者物理上分割存放2、对象标识符 Postg…

Weblogic SSRF 漏洞(CVE-2014-4210)

SSRF漏洞 ​ SSRF&#xff08;服务端请求伪造&#xff09;&#xff0c;指的是攻击者在未能取得服务器所有权限时&#xff0c;利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统。 ​ 简单的说就是利用一个可…

《统计学习方法》——隐马尔可夫模型(下)

学习算法 HMM的学习&#xff0c;在有观测序列的情况下&#xff0c;根据训练数据是否包含状态序列&#xff0c;可以分别由监督学习算法和无监督学习算法实现。 监督学习算法 监督学习算法就比较简单&#xff0c;基于已有的数据利用极大似然估计法来估计隐马尔可夫模型的参数。…

详解二叉树

&#x1f308;目录 一、树形结构​ &#x1f333;1.1 概念1.2 其他概念1.3 树的表示形式 二、二叉树✨2.1 概念2.2 两种特殊二叉树2.3 性质2.4 二叉树存储 三、二叉树的基本操作&#x1f64c;3.1 前置说明3.2 二叉树的遍历3.3 二叉树的基本操作 四、二叉树的OJ✍️ 一、树形结构…

springboot+vue医院信管系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的医院信管系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌&a…

Service Control Manager 服务管理器简介

在windows驱动开发流程中&#xff0c;写完sys驱动binary之后&#xff0c;为了让OS能够正确的从注册表中读取到对应的信息&#xff0c;并且将其load运行起来&#xff0c;还需要编写inf文件来描述配置驱动文件。不过这也不是必须的&#xff0c;可以通过ServiceControlManager直接…

Fiddler 抓包工具 - 全网最全最细教程,没有之一

Fiddler 简介 Fiddler 是位于客户端和服务器端的 HTTP 代理 目前最常用的 http 抓包工具之一 功能非常强大&#xff0c;是 Web 调试的利器 监控浏览器所有的 HTTP/HTTPS 流量 查看、分析请求内容细节 伪造客户端请求和服务器响应 测试网站的性能解密 HTTPS 的 Web 会话 全局…

Go语音基于zap的日志封装

zap日志封装 Zap是一个高性能、结构化日志库&#xff0c;专为Go语言设计。它由Uber开源&#xff0c;并且在Go社区中非常受欢迎。它的设计目标是提供一个简单易用、高效稳定、灵活可扩展的日志系统。 以下是Zap的一些主要特点&#xff1a; 1.高性能&#xff1a;Zap的性能非常出…

【Linux】权限的理解

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…

mysql exist和in的区别

一、演示用的表 为了演示二者的区别&#xff0c;先建立两张表 user 表和 order 表 二、in 的执行情况 in在查询的时候&#xff0c;首先查询子查询的表&#xff0c;然后将内表和外表做一个笛卡尔积&#xff0c;然后按照条件进行筛选。所以相对内表比较小的时候&#xff0c;…

接口测试之Jenkins+Jmeter+Ant实现持续集成

安装Jenkins&#xff0c;见手把手教小白安装Jenkins_程序员馨馨的博客-CSDN博客 一&#xff09;Linux机器上安装Jmeter 百度一下就好 二&#xff09;Linux机器上安装Ant 1、下载安装包 进入Apache Ant - Binary Distributions&#xff0c;下载安装包&#xff0c;本次安装的是版…

高仿某东商城flutter版本,个人学习flutter项目

前言 高仿某东商城flutter版本&#xff0c;个人学习flutter项目 使用flutter_redux状态管理网络使用dio进行了简单的封装使用node项目mock服务端接口(mock_server目录)目前只实现了首页&#xff0c;其他功能持续更新… 同款Android Kotlin版本&#xff08; https://github.co…

Mysql索引底层原理及其优化方案

1.深入理解Mysql索引底层数据结构与算法 1.1索引结构 索引及其数据结构&#xff1a; 二叉树红黑树Hash表B-Tree 1.1 二叉树 说明&#xff1a;二叉树是建立数据后&#xff0c;会和第一元素进行比对&#xff0c;当比较的元素小于第一个元素时&#xff0c;此时就会走第一个元素…

代码随想录算法训练营第四十三天 | 填满背包有几种方法、背包有两个维度

1049.最后一块石头的重量II 文档讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;动态规划之背包问题&#xff0c;这个背包最多能装多少&#xff1f;LeetCode&#xff1a;1049.最后一块石头的重量II_哔哩哔哩_bilibili 状态&#xff1a;没想到。 思路 本…

chatgpt如何引入领域知识?mit团队利用gpt4做数据增强来提升小模型在特定领域的效果

一、概述 title&#xff1a;Dr. LLaMA: Improving Small Language Models in Domain-Specific QA via Generative Data Augmentation 论文地址&#xff1a;Paper page - Dr. LLaMA: Improving Small Language Models in Domain-Specific QA via Generative Data Augmentation…