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

【计算机网络】什么是socket编程?以及相关接口详解

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶🔹C++🔹Liunx
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

在这里插入图片描述

一、 什么是socket套接字

我们使用一张图片很形象的可以看出socket所处的位置。

在这里插入图片描述
从用户层面来看:

从上图看出,Socket处于应用层传输层的中间软件抽象层,它是一组接口。并且前面我们也学过,运输层和网络层其实属于操作系统内层面,我们只给用户提供使用的接口即可,不可能让用户能直接访问到内核部分。
在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

从操作系统层面来看:
linux下一切皆文件!!!所以本质来说Socket即是一种特殊的文件,一些socket函数【bind()、listen()等等】,就是对这个文件进行的操作(读/写IO、打开、关闭)

二、Socket函数接口详解

// 创建 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);

上面的参数中带有 struct sockaddr*结构体,这是个什么呢?

首先我们要知道socket的英文为插座,而我们的ip+端口号可以决定是哪一台主机上的哪一个进程,相当于一个插头,谁插入这个socket插槽,谁就可以与之通信。

套接字的分类及struct sockaddr*

1.网络套接字

2.原始套接字

3.unix域间套接字

这个struct sockaddr*结构体是一个父类一般还有两个衍生的子类,他们一个sockaddr_in(inet,网络通信)主要用于网络间的通信同时也支持本地,另一个sockaddr_un(域间套接字)只能在本地通信。而原始套接字可以跨过传输层(TCP/IP协议)访问底层的数据

网络套接字
struct sockaddr_in {short int sin_family;  // 地址族,一般为AF_INET(IPv4)和AF_INET6(IPv6)unsigned short int sin_port; // 端口号,网络字节序struct in_addr sin_addr; // IP地址unsigned char sin_zero[8];// 用于填充,使sizeof(sockaddr_in)等于16
};原始套接字
struct sockaddr {sa_family_t sa_family; 		/* address family, AF_xxx */char sa_data[14];//sa_data是一个字节数组,用于存储地址和端口号信息的具体内容,具体内容的长度和格式依赖于协议族的不同。
};unix域间套接字
struct sockaddr_un {sa_family_t sun_family;       /* AF_UNIX */char sun_path[108];    /* 带有路径的文件名 */
};//通过同一个文件的路径来让进程看到同一份资源

其中还有一个结构体是struct in_addr,这个函数内部如下:


struct in_addr {uint32_t    s_addr;   /* address in network byte order */
};

简单来说原始套接字使用了一个sa_data数组将IP和端口号存储在了一起,很多网络编程函数诞生早于IPv4协议,那时候都使用的是sockaddr结构体。但是sockaddr的缺陷是:sa_data把目标地址和端口信息混在一起了。IPv4为了解决这个问题,于是便设计了sockaddr_in专门用于网络通信结构体,把port和ip分开来存储。

sockaddr_in 是用于 IPv4 地址的特定地址结构体。它扩展了 sockaddr,并提供了 IPv4 地址(通过 sin_addr 字段存储)和端口号(通过 sin_port 字段存储)的字段。sockaddr_in 使用的是网络字节序(大端字节序)来存储这些值。如果不知道网络字节序请搜索一下。

在这里插入图片描述

1.socket

格式:

int socket(int domain, int type, int protocol);

参数:

  • domain:指定套接字的协议族,如AF_INET(IPv4)或AF_INET6(IPv6)。
    type:指定套接字的类型。
       SOCK_STREAM(面向连接的流套接字)
      SOCK_DGRAM(无连接的数据报套接字)。
    protocol:指定使用的传输协议,通常可以设置为0以自动选择合适的协议。

返回值:返回一个int型的数字来表示套接字

作用创建一个套接字,将domain、type和protocol参数传递给socket()函数以指定套接字的特性,并返回一个int型套接字描述符,用于后续的操作。

2.bind

格式:

int bind(int socket, const struct sockaddr *addr,socklen_t addrlen);

参数:

  • sockfd:要绑定的套接字描述符,也就是socket函数的返回值
  • addr:是一个指向 sockaddr 结构的指针,该结构包含了要绑定的IP地址和端口号。
  • addrlen:指定addr结构体的大小。

返回值

  • bind函数的返回值用于指示操作是否成功:
    如果 bind 函数成功执行,它将返回 0。
    如果 bind 函数执行失败,它将返回 -1,并设置全局变量 errno 以指示错误的具体原因。

作用:bind函数用于将一个套接字(socket)与特定的IP地址和端口号绑定

3.listen

格式:

int listen(int socket, int backlog)

参数:

  • socket:要设置为监听状态的套接字描述符。
  • backlog:指定等待连接队列的最大长度,用于限制同时可以等待处理的连接请求的数目

返回值

  • 成功时:当listen函数成功地将套接字置于监听状态时,它返回0。这表示服务器已经准备好接受客户端的连接请求。
  • 失败时:如果listen函数执行失败,它将返回-1,并设置全局变量errno以指示错误的具体原因。此时,可以通过检查errno的值来确定错误类型,并据此采取相应的错误处理措施。

错误码:

EADDRINUSE:表示地址已被使用,即尝试监听的端口已被其他进程占用。
EINVAL:表示无效的参数,可能是因为套接字未绑定地址,或者该套接字已被连接(对于某些类型的套接字,如SOCK_DGRAM,监听操作可能不被允许)。
ENOTSOCK:表示文件描述符不是一个套接字。
WSAENETDOWN(Windows特有):表示网络子系统失效。
WSAEINPROGRESS(Windows特有):表示一个阻塞的套接字调用正在运行中。
WSAEMFILE(Windows特有):表示无可用文件描述符。
WSAENOBUFS(Windows特有):表示无可用缓冲区空间。

作用: 将套接字设置为监听状态,开始接受客户端的连接请求。通过指定backlog参数,可以控制连接队列的长度。

4.accept

格式:

int accept(int socket, struct sockaddr* address,
socklen_t* address_len)

参数:

  • sockfd:监听 套接字描述符。
  • addr:用于存储客户端的地址信息的结构体指针,可以是struct sockaddr、struct sockaddr_in或struct sockaddr_in6等类型的指针。
  • addrlen:指向一个整数变量,用于传递addr结构体的大小,并在接受连接后更新为实际的地址长度。

返回值

  • 成功时的返回值
    当accept函数成功接受一个客户端的连接请求时,它会返回一个非负值。这个非负值就是新创建的socket文件描述符或对象的标识符,用于后续的通信操作。

  • 失败时的返回值
    如果accept函数在尝试接受连接请求时遇到错误(例如,监听socket已经被关闭),它将返回-1,并设置全局变量errno以指示错误的具体原因。此时,可以通过检查errno的值来确定错误类型,并据此采取相应的错误处理措施。

作用: 等待并接受客户端的连接请求,并返回一个新的套接字描述符,该描述符用于与客户端进行通信。同时,可以获取客户端的地址信息

5.connet

格式:


int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

参数:

  • sockfd:要进行连接的套接字描述符。
  • addr:要连接的目标地址的结构体指针,该结构包含了要绑定的IP地址和端口号。
  • addrlen:指定addr结构体的大小。

返回值

  • 成功时的返回值
    当connect函数成功地将客户端套接字与服务器套接字连接起来时,它返回0。这表示连接已经成功建立,客户端可以继续通过该套接字发送和接收数据。
  • 失败时的返回值
    如果connect函数在尝试建立连接时遇到错误(如网络不可达、服务器未运行、服务器拒绝连接等),它将返回-1,并设置全局变量errno以指示错误的具体原因。此时,可以通过检查errno的值来确定错误类型,并据此采取相应的错误处理措施。

错误码

ECONNREFUSED:表示连接被远程计算机拒绝。这通常意味着没有服务在目标端口上监听,或者服务器程序拒绝连接请求。
ENETUNREACH:表示网络不可达。这可能是因为网络线路故障、路由表配置错误或远程主机不可达等原因。
ETIMEDOUT:表示连接超时。这可能是因为远程主机没有响应连接请求,或者连接请求在传输过程中被延迟或丢失。
EINPROGRESS(在非阻塞模式下):表示连接操作正在进行中。在非阻塞模式下,connect函数可能无法立即完成连接操作,此时将返回-1,并将errno设置为EINPROGRESS。在这种情况下,需要调用其他函数(如select、poll或epoll)来检查连接是否成功建立。

作用: 与另一个套接字建立连接,通常用于客户端连接服务器。通过指定目标地址和端口号,使套接字能够与目标进行通信。

6.读写操作

以下函数均可读取Socket数据

   ssize_t read(int fd, void *buf, size_t count);ssize_t write(int fd, const void *buf, size_t count);ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t recv(int sockfd, 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 recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

主要来说说recvfrom和sendto函数

在这里插入图片描述

recvfrom参数中的addr的意义就是获取发送发放的信息,便于之后使用sento发送时使用。

7.close()函数

在服务器与客户端建立连接之后,会进行一些读写操作,完成了读写操作就要关闭相应的socket描述字,好比操作完打开的文件要调用fclose关闭打开的文件。

8.字节序转换接口

#include<arpa/inet.h>

uint32_t    htonl(uint32_t hostlong);    //32位整数从主机字节序转换为网络字节序
uint16_t    htons(uint16_t hostshort);   //16位整数从主机字节序转换为网络字节序
uint32_t    ntohl(uint32_t netlong):     //32位整数从网络字节序转换为主机字节序
uint16_t    ntohs(uint16_t netshort);    //16位整数从网络字节序转换为主机字节序

9.IP地址格式转换函数

//点分十进制的IP地址字符串转换成in_addr_t类型
in_addr_t inet_addr(const char *cp)
//将结构struct in_addr中的二进制IP地址转换为一个点分十进制
char *inet_ntoa(struct in_addr in)

相关文章:

【计算机网络】什么是socket编程?以及相关接口详解

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

LeetCode.19.删除链表的倒数第n个节点

题目描述&#xff1a; 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点 输入输出实例&#xff1a; 思路&#xff1a;这道题目我们可以用双指针来做&#xff0c;让first和second指针之间的距离为n1&#xff0c;然后我们first和second指针…...

vue-cesium

vue-cesium: Vue 3.x components for CesiumJS. cesium 文档中文版 ArcGisMapServerImageryProvider - Cesium Documentation all参考 https://juejin.cn/post/7258119652726341669 cesium官网 Cesium Sandcastle...

《npm 学习过程中遇到的诸多问题》

npm 开发 1.开发过程中难免会使用到npm ,进行安装第三方包 遇到的问题 match 报错&#xff1a;npm i报错npm ERR! Cannot read property match of undefined 可以尝试清除本地的package-log.json 文件&#xff0c;再试试...

CentOS 介绍

引出 Linux 系统内核与 Linux 发行套件系统的区别&#xff1f; Linux 系统内核指的是一个由 Linus Torvalds&#xff08;Linux之父&#xff0c;内核主要开发者&#xff09;负责维护&#xff0c;提供硬件抽象层、磁盘、文件系统控制及多任务功能的系统核心程序。 Linux 发行套…...

模拟面试题1

目录 一、JVM的内存结构&#xff1f; 二、类加载器分为哪几类&#xff1f; 三、讲一下双亲委派机制 为什么要有双亲委派机制&#xff1f; 那你知道有违反双亲委派的例子吗&#xff1f; 四、IO 有哪些类型&#xff1f; 五、Spring Boot启动机制 六、Spring Boot的可执行…...

CTFHUB-web-RCE-综合过滤练习

开启题目 查看网页源代码发现这次网页对 | 、 && 、 || 、 \ 、 / 、; &#xff0c;都进行了过滤处理 发现换行符 %0a 和回车符 %0d 可以进行测试&#xff0c;在 URL 后面拼接访问 127.0.0.1%0als 用 ls flag_is_here 查看 flag 文件中的内容&#xff0c;发现回显为空…...

Leetcode75-7 除自身以外数组的乘积

没做出来 本来的思路是遍历一遍得到所有乘积和然后除就行 但是题目不能用除法 答案的思路 for(int i0;i<n;i) //最终每个元素其左右乘积进行相乘得出结果{res[i]*left; //乘以其左边的乘积left*nums[i];res[n-1-i]*right; //乘以其右边的乘积right*nums[n-1-i]…...

AI绘画工具介绍:以新奇角度分析与探索AI绘画艺术与技术的交汇点

目录 前言 一、AI绘画工具的前沿技术 1.1 深度学习的进化 1.2 GANs的创新应用 1.3 风格迁移的多样化 1.4 交互式AI绘画的智能化 二、艺术与技术的交汇点 2.1 艺术创作的普及化 2.2 艺术风格的创新 2.3 艺术与科技的深度融合 三、新颖的思考角度 3.1 AI作为艺术创作…...

基于Springboot + Vue的宿舍管理系统

前言 文末获取源码数据库 感兴趣的可以先收藏起来&#xff0c;需要学编程的可以给我留言咨询&#xff0c;希望帮助更多的人 精彩专栏推荐订阅 不然下次找不到哟 Java精品毕设原创实战项目 作者的B站地址&#xff1a;程序员云翼的个人空间-程序员云翼个人主页-哔哩哔哩视频 csd…...

CTFHUB-web-RCE-eval执行

开启题目 查看源码发现直接用蚁剑连接就可以&#xff0c;连接之后发现成功了...

Oracle DBA常用 sql

文章目录 一、基础环境二、常用 sql三、参考资料 版权声明&#xff1a;本文为CSDN博主「杨群」的原创文章&#xff0c;遵循 CC 4.0 BY-SA版权协议&#xff0c;于2023年7月6日首发于CSDN&#xff0c;转载请附上原文出处链接及本声明。 原文链接&#xff1a;https://blog.csdn.n…...

MindSearch:AI 时代的“思考型”搜索引擎

随着AI技术的飞速发展&#xff0c;搜索引擎领域也迎来了新的变革。继 OpenAI 发布 SearchGPT 之后&#xff0c;国内也涌现出一批优秀的AI搜索引擎&#xff0c;其中&#xff0c;由中科大和上海人工智能实验室联合研发的 MindSearch&#xff08;思索&#xff09;尤为引人注目。这…...

机器学习练手(四):基于SVM 的肥胖风险分类

总结&#xff1a;本文为和鲸python 机器学习原理与实践闯关训练营资料整理而来&#xff0c;加入了自己的理解&#xff08;by GPT4o&#xff09; 原活动链接 原作者&#xff1a;vgbhfive&#xff0c;多年风控引擎研发及金融模型开发经验&#xff0c;现任某公司风控研发工程师&…...

AutoGPT项目实操总结

AutoGPT项目介绍 AutoGPT是一个基于GPT-4的开源项目&#xff0c;旨在简化用户与语言模型的交互过程&#xff0c;使文本生成和信息收集更轻松、更高效。它具备互联网搜索、长短期记忆管理、调用大模型进行文本生成、存储和总结文件等能力&#xff0c;并且可以通过插件扩展功能与…...

uniapp 荣耀手机 没有检测到设备 运行到Android手机 真机运行

背景&#xff1a; 使用uniapp框架搭建的项目&#xff0c;开发的时候在浏览器运行&#xff0c;因为项目要打包成App&#xff0c;所以需要真机联调&#xff0c;需要运行到Android手机&#xff0c;在手机上查看/运行项目。通过真机调试才能确保软件开发的准确性和页面显示的完整性…...

【EtherCAT】Windows+Visual Studio配置SOEM主站——静态库配置+部署

目录 一、准备工作 1. Visual Studio 2022 2. Npcap 1.79 3. SOEM源码 二、静态库配置 1. 修改SOEM源码配置 2. 编译SOEM源码 3. 测试 三、静态库部署 1. 新建Visual Studio工程 2. 创建文件夹 3. 创建主函数 4. 复制静态库 5. 复制头文件 6. 配置头文件…...

【Python小游戏示例:猜拳游戏】

当然可以&#xff01;以下是一个简单的Python小游戏示例&#xff1a;猜拳游戏。在这个游戏中&#xff0c;玩家将与计算机进行猜拳&#xff08;石头、剪刀、布&#xff09;。 import randomdef get_computer_choice():choices [石头, 剪刀, 布]return random.choice(choices)d…...

多态实现的必要条件,实现多态的三个方法,输入一个URL的过程,死锁产生的原理和条件,进程和线程的定义及区别,进程通信的几种方式

继承:面相对象编程中的核心概念,子类可以使用父类的属性和方法,无需重新编写,子类还可以添加新的属性和方法来提供特定的实现多态:同一件事,发生在不同的对象上,会产生不同的结果,传递不同的对象会调用对应类中的方法重载(Overload),同一个类中多个同名的方法,参数列表不同,提高…...

Springboot+MybatisPlus项目中,数据库表中存放Date,查出后转为String

新增一条记录时&#xff0c;数据库表中会有一个gmt_created 的字段&#xff0c;存放创建时间。 该值在数据库中的默认值为&#xff1a;CURRENT_TIMESTAMP 在对应的JavaBean中&#xff0c;该值为 gmtCreated&#xff0c; 那么问题来了&#xff1a; 如何让在表中的Date类型&…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...