IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【网络篇】套接字编程 -> 正文阅读

[系统运维]【网络篇】套接字编程

1、前提知识铺垫

1.1 认识端口—port

本质端口号是一个2字节16位的无符号整数,范围是[0,65535]

作用端口号是用来标识一个进程,告诉操作系统,当前的数据要交给那一个进程来处理

注意事项

一个端口只能被一个进程占用
一个进程可以占用多个端口

一些知名端口

[0,1023] 范围内的端口已经被一些知名的协议所使用,我们在编写代码的时候不要使用该范围内的数据作为端口号
MySQL----3306端口
Oracle----1521端口

1.2 网络数据的五元组信息

{源IP、 目的IP 、源端口、目的端口、 协议}

名称作用
源IP标识网络数据是从哪台主机发出的
目的IP标识数据要去往哪一台主机
源端口标识网络数据是从“源IP”对应的这台主机的哪个进程产生的
目的端口通过目的IP找到目的主机之后,需要利用目的端口找到对应的进程
协议标定双方传输数据时使用的协议,一般是UDP/TCP

1.3 网络字节序

??字节序又称为端序或者尾序指的是多字节数据在内存中存放的顺序

我们接触的字节序分为两类:小端字节序大端字节序
他们是两种数据在内存中存放顺序的不同规则

字节序特点
小端字节序数据的低权值位对应空间的低地址
大端字节序数据的低权值位对应空间的高地址

如何判断自己的机器遵守的是哪一种存储规则?

方式一:指针+变量+强制类型转换验证
在这里插入图片描述
方式二:利用联合体的存储特性来判断
在这里插入图片描述
有了上面的铺垫,我们来认识一下主机字节序与网络字节序

主机字节序:指的是机器本身的字节序,如果是大端,则主机字节序为大端,如果是小端,则主机字节序为小端

网络字节序规定网络传输数据的时候采用大端字节序进行传输

1.4 主机字节序与网络字节序的相互转换

既然网络字节序是大端字节序,现在假设有AB两台主机,他们之间需要通过网络进行通信,我们分析A向B发送消息这一单程。

A向B发送的数据,通过网络传输时一定要转换为网络字节序,否则传输的数据可能会出错(这取决于主机A是大端还是小端机器)

B从网络中接收A发送的数据时,也需要将数据从网络字节序转换为B主机的主机字节序

这个具体的转换过程并不需要我们自己实现,OS为我们提供了转换的接口

在这里插入图片描述

1.5 TCP协议与UDP协议的特性和区别

UDP:
在这里插入图片描述
TCP
在这里插入图片描述

2、UDP_socket编程

2.1 编程流程

服务端

Ⅰ、创建套接字
Ⅱ、绑定地址信息
Ⅲ、收发消息
Ⅳ、使用完毕后关闭套接字

客户端

Ⅰ、创建套接字
Ⅱ、不推荐绑定地址信息
??不推荐在代码手动绑定地址信息
Ⅲ、收发消息
Ⅳ、使用完毕后关闭套接字

图示:在这里插入图片描述
总结:
1、为什么要创建套接字?
??将进程和网卡进行绑定,进程可以从网卡中接收消息,也可以通过网卡发送消息。
2、绑定地址信息具体干了什么?
??绑定IP和端口。目的是为了在网络中表示一台主机和一个进程。这样一来,对于接收方而言,发送数据的人就知道接受方的在哪台机器的哪个进程了;对于发送方而言,能够标识网络数据是从哪台机器的哪个进程发送出去的。

2.2 编程接口

2.2.1 创建套接字

#include<sys/socket.h>

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

参数:
在这里插入图片描述
返回值:
在这里插入图片描述

2.2.2 绑定接口

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

参数:
sockfd-----创建套接字时返回的套接字描述符
addr-----绑定的地址信息(IP + port)
addrlen----绑定的地址信息的长度

注意:这里的 struct sockaddr是一个通用的数据结构!结构如下:
在这里插入图片描述
我们在组织参数的时候,传递的并不是上面的这个通用数据结构,而是struct sockaddr_in这个结构体变量,具体内容如下:
在这里插入图片描述

2.2.3 发送接口

ssize_t sendto(int sockfd, const void* buf, size_t len, int flags,const struct sockaddr* dest_addr, socklen_t addrlen);

参数:
在这里插入图片描述
返回值:
在这里插入图片描述

2.2.4 接收接口

ssize_t recvfrom (int sockfd, void* buf, size_t len, int flags,struct sockaddr* src_addr, socklen_t* addrlen);

参数:
在这里插入图片描述

2.2.5 关闭接口

int close(int fd)

2.3 编程代码

在这里插入图片描述
具体代码---->点这里

3、TCP_socket编程

3.1 编程流程

服务端

创建套接字
绑定地址信息
监听
获取新连接

收发数据
关闭连接

客户端

创建套接字
不推荐绑定地址信息
发起连接
收发数据
关闭连接

图示:
在这里插入图片描述
总结:
监听的含义
?监听TCP客户端新的连接,同客户端建立TCP连接。(此时,TCP的建立在内核中就完成了)
获取新连接的含义
?获取新连接的套接字描述符,每一个TCP连接会产生一个新的套接字描述符
发起连接的含义
?向服务端发起连接

3.2 编程接口(较UDP编程新增的接口)

3.2.1 监听接口

int listen(int sockfd, int backlog)

参数
在这里插入图片描述返回值
成功—>0
失败—>-1

3.2.2 获取新连接

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

在这里插入图片描述
关于获取新连接这一接口的理解:
在这里插入图片描述

3.2.3 发起连接

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

在这里插入图片描述
在这里插入图片描述

3.2.4 收发数据

接收数据:

ssize_t recv(int sockfd, void* buf, size_t len, int flags);

在这里插入图片描述
注意:返回值为0表示对端关闭连接了,如果此时的对端指的是客户端,则服务端需要将对应的新套接字描述符关闭!

发送数据

ssize_t send(int sockfd, const void* buf, size_t len, int flags)

在这里插入图片描述
注意:
?服务端在发送数据的时候,第一个参数sockfd传递的是新创建的套接字描述符,并不是侦听套接字的套接字描述符

3.3 编程代码

期望完成的功能:服务端和多个客户端之间能够正常的通信!

3.3.1 TCP_demo

服务端主要代码:
在这里插入图片描述
客户端主要代码 :
在这里插入图片描述
运行结果分析:
在这里插入图片描述
分析出现这种情况的原因:
?首先,第二个客户端的代码能够执行到提示输入语句处,说明此时该客户端与服务端已经建立了连接。并且客户端发送数据后没有报错,说明客户端数据发送是成功的。因此问题肯定是出在服务端的代码。
我们可以通过命令netstat来查看当前网络连接状态以及相关信息。
在这里插入图片描述
综上所述,我们单线程的TCP代码就目前而言,只能服务于单个客户端的情况。(注意:后续可以通过多路转接IO模型实现服务器与客户端是一对多的现象)

TCP_demo客户端代码
TCP_demo服务端代码

基于这种情况,我们需要找到一种方法,能够同时让多个客户端都享受服务。
因此,我们可以让服务端的一个进程(线程)只负责与客户端建立连接,剩下的一批进程(线程)可以各自与一个客户端进行沟通。这样就可以达到我们的目标了。因此TCP结合多进程/多线程就脱颖而出~

下面分别介绍TCP 与多进程和多线程结合的代码

3.3.2 TCP + 多进程

首先,对于客户端的代码而言,不需要做出任何的改动!因为客户端只需要一直和服务端进行通信即可!

主要的更改是在服务端,我们通过创建子进程的方式来实现职责的分离,也就是父进程只负责与客户端建立连接,而子进程负责与客户端进行收发消息。
具体核心代码如下:
在这里插入图片描述
注意几点细节:
1、子进程是拷贝父进程的PCB,因此需要父进程先与客户端建立连接,也即在父进程的PCB中的fd_array中有了该套接字的文件描述符之后再创建子进程
2、子进程创建成功过,由于它只需要和客户端进行收发消息,因此只需要accept返回的新套接字描述符即可,所以需要将拷贝自父进程的侦听套接字关闭
3、客户端如果将连接关闭,则子进程需要将对应的套接字即文件描述符关闭,然后该进程需要退出。
但是注意:退出时,一定要通知父进程来回收子进程的退出状态信息,否则子进程就会编程僵尸进程!但是我们不能采用wait || waitpid来回收。因为wait具有阻塞属性,而waitpid需要搭配循环来使用,均不符合我们的预期。我们可以通过信号量的方式来处理,即改写SIGCHLD信号!

具体代码参考 TCP_process服务端

3.3.3 TCP + 多线程

在这里插入图片描述
在这里插入图片描述
具体代码参考—TCP_thread服务端代码

以上就是关于socket编程的相关总结~感觉有所帮助的友友们欢迎评论转发!!
在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-06-14 22:57:06  更:2022-06-14 22:59:00 
 
开发: 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年5日历 -2024/5/19 0:30:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码