Linux网络编程:Socket套接字编程(Server服务器 Client客户端)
文章目录:
一:定义和流程分析
1.定义
2.流程分析
3.网络字节序
二:相关函数
IP地址转换函数inet_pton inet_ntop(本地字节序 网络字节序)
socket函数(创建一个套接字)
bind函数(给socket绑定一个服务器地址结构(IP+port))
listen函数(设置最大连接数或者说能同时进行三次握手的最大连接数监听上限)
accept函数(阻塞监听等待客户端建立连接, 成功的话返回一个与客户端成功连接的socket文件描述符)
connect函数(使用现有的socket与服务器建立连接)
三:服务器模型和客户端模型的实现
Server服务器的实现
Client客户端的实现
一:定义和流程分析
1.定义
定义:一个文件描述符指向一个套接字(该套接字内部由内核借助两个缓冲区实现)在通信过程中, 套接字一定是成对出现的一种文件类型,伪文件,不占用存储空间,可进行IO操作,可间接看做文件描述符使Socket本身有“插座”的意思在Linux环境下,用于表示进程间网络通信的特殊文件类型。本质为内核借助缓冲区形成的伪文件管道, 套接字, 块设备, 字符设备;套接字: 一个fd可以索引读写两个缓冲区;
2.流程分析
socket():创建一个套接字, 用fd索引bind():绑定IP和portlisten():设置监听上限(同时与Server建立连接数)accpet():阻塞监听客户端连接(传入一个上面创建的套接字, 传出一个连接的套接字)在客户端中的connect()中绑定IP和port,并建立连接(阻塞)
3.网络字节序
小端法:(pc本地存储) 高位存高地址。低位存低地址。 int a = 0x12345678 大端法:(网络存储) 高位存低地址。低位存高地址。htonl --> 本地--》 网络 (IP) 192.168.1.11 --> string --> atoi --> int --> htonl --> 网络字节序 htons --> 本地--》 网络 (port) ntohl --> 网络--》 本地(IP) ntohs --> 网络--》 本地(Port)
用库函数做网络字节序和主机字节序的转换
#include<arpa/inet.h> uint32_t htonl(uint32_t hostlong); //主要针对IP uint16_t htons(uint16_t hostshort); //主要针对port uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);
二:相关函数
IP地址转换函数inet_pton inet_ntop(本地字节序 网络字节序)
由于如
192.168.45.2
这种的IP地址为点分十进制表示,需要转化为uint32_t
型,有现成的函数(IPv4和IPv6都可以转换)//本地字节序(string IP) ---> 网络字节序 int inet_pton(int af, const char *src, void *dst); af:AF_INET、AF_INET6src:传入,IP地址(点分十进制)dst:传出,转换后的 网络字节序的 IP地址。 返回值:成功: 1异常: 0, 说明src指向的不是一个有效的ip地址。失败:-1//网络字节序 ---> 本地字节序(string IP) const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); af:AF_INET、AF_INET6src: 网络字节序IP地址dst:本地字节序(string IP)size: dst 的大小。返回值: 成功:dst、失败:NULL
socket函数(创建一个套接字)
#include <sys/socket.h>int socket(int domain, int type, int protocol); 创建一个 套接字domain指定使用的协议(IPv4或IPv6)AF_INET 这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址AF_INET6 与上面类似,不过是来用IPv6的地址AF_UNIX 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用type指定数据传输协议(流式或报式)SOCK_STREAM 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。SOCK_DGRAM 这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。SOCK_SEQPACKET该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。SOCK_RAW socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)SOCK_RDM 这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序指定代表协议(一般默认传0)protocol: 0 流式以TCP为代表;报式以UDP为代表;返回值:返回指向新创建的socket的文件描述符成功:返回新套接字所对应文件描述符fd失败:返回-1并设置errno;
bind函数(给socket绑定一个服务器地址结构(IP+port))
#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 给socket绑定一个 地址结构 (IP+port)sockfd: socket文件描述符struct sockaddr_in servaddr;addr.sin_family = AF_INET;addr.sin_port = htons(8888);addr.sin_addr.s_addr = htonl(INADDR_ANY);addr: 构造出IP地址加端口号传入参数(struct sockaddr *)&addraddrlen: sizeof(addr) 地址结构的大小返回值:成功:0失败:返回-1, 设置errno
listen函数(设置最大连接数或者说能同时进行三次握手的最大连接数监听上限)
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>int listen(int sockfd, int backlog); //设置同时与服务器建立连接的上限数(同时进行3次握手的客户端数量)sockfd:socket文件描述符backlog:上限数值。最大值 128排队建立3次握手队列和刚刚建立3次握手队列的链接数和返回值:成功:0失败:-1 errno
accept函数(阻塞监听等待客户端建立连接, 成功的话返回一个与客户端成功连接的socket文件描述符)
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);sockfd:socket文件描述符addr:成功与Sever建立连接的那个**客户端**的地址结构;传出参数,返回链接客户端地址信息(IP地址+端口号)addrlen:传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小 socklen_t clit_addr_len=sizeof(addr); 入: 传入addr的大小; 出: 客户端addr的实际大小;返回值: 成功: 返回能与客户端进行通信的socket对应的文件描述符; 失败: 返回-1并设置errno;//我们的服务器程序结构是这样的 while (1) {cliaddr_len = sizeof(cliaddr);connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);n = read(connfd, buf, MAXLINE);......close(connfd); }
connect函数(使用现有的socket与服务器建立连接)
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);sockdf:socket文件描述符struct sockaddr_in srv_addr; // 服务器地址结构srv_addr.sin_family = AF_INET;srv_addr.sin_port = 9527 跟服务器bind时设定的 port 完全一致。inet_pton(AF_INET, "服务器的IP地址",&srv_adrr.sin_addr.s_addr);addr:传入参数,指定服务器端地址信息,含IP地址和端口号addrlen:传入参数,服务器地址结构的长度sizeof(addr)大小返回值: 成功返回0; 失败返回-1并设置errno;如果不使用`bind()`函数绑定客户端的地址结构, 会采用**"隐式绑定"**;
三:服务器模型和客户端模型的实现
Server服务器的实现
server:1. socket() 创建socket2. bind() 绑定服务器地址结构3. listen() 设置监听上限4. accept() 阻塞监听客户端连接5. read(fd) 读socket获取客户端数据6. 小--大写 toupper()7. write(fd)8. close();
代码逻辑
#include <stdio.h> #include <ctype.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <pthread.h>#define SERV_PORT 9527 //端口号int main(int argc, char *argv[]){int link_fd=0; //建立连接的socket文件描述符int connect_fd=0 //用于通信的文件描述符int ret=0; //用于检查是否出错char buf[BUFSIZ]; //缓冲区char client_IP[1024] //存入客户端IP字符串int num=0; //读出的字节数/*服务器端地址结构*/struct sockaddr_in serv_addr; // 定义服务器地址结构 和 客户端地址结构serv_addr.sin_family=AF_INET; // IPv4serv_addr.sin_port=htons(SERV_PORT); // 转为网络字节序的 端口号serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); // 获取本机任意有效IP/*成功与服务器建立连接的客户端地址结构*/struct sockaddr_in clint_addr;socklen_t clint_addr_len=sizeof(clint_addr); // 获取客户端地址结构大小/*1.socket函数:创建用于建立连接的socket,返回的文件描述符存入link_fd*///IPv4,按照顺序基于字节流的连接,指定代表协议link_fd=socket(AF_INET,SOCK_STREAM,0); if(link_fd==-1)sys_err("socket error");/*2.bind函数:绑定服务器端的socket绑定地址结构(IP+port)*///socket文件描述符link_fd,IP地址加端口号ret=bind(link_fd,(const struct sockaddr*)&serv_addr,sizeof(serv_addr));if(ret==-1)sys_err("bind error");/*3.listen函数:设定监听(连接)上线*/ret=listen(link_fd,128); if(ret==-1)sys_err("listen error");/*4.accept函数:阻塞等待客户端建立连接*///文件描述符,与Sever建立连接的客户端的地址结构,返回真正接收到地址结构体的大小connect_fd=accept(link_fd,( struct sockaddr*)&clint_addr,&clint_addr_len); if(connect_fd==-1)sys_err("accept error");/*建立连接后打印客户端的IP和端口号 获取客户端地址结构*/printf("client IP:%s,client port:%d", //`client_IP`是前面定义的客户端IP字符串的缓冲区, 大小为1024 inet_ntop(AF_INET,&clint_addr.sin_addr.s_addr,client_IP,sizeof(client_IP)), //网络字节序 ---> 本地字节序ntohs(clint_addr.sin_port) //根据accept传出参数,获取客户端 ip 和 port); /*业务逻辑*/while(1){//5. read(fd) 读socket获取客户端数据num=read(connect_fd,buf,sizeof(buf)); // 读客户端数据write(STDOUT_FILENO,buf,num); // 写到屏幕查看//6. 小--大写 toupper()for(i=0;i<num;i++) // 小写 -- 大写buf[i]=toupper(buf[i]);//7. write(fd)write(connect_fd,buf,num); // 将大写,写回给客户端sleep(1);}//8. close()close(connect_fd);close(link_fd);return 0; }
测试命令
`nc 127.0.0.1 9527` //脑残命令: 向这个服务发送信息并打印回执
Client客户端的实现
client:1. socket() 创建socket2. connect(); 与服务器建立连接3. write() 写数据到 socket4. read() 读转换后的数据5. 显示读取结果6. close()
代码逻辑
#include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <pthread.h>#define SERV_PORT 9527/*错误处理函数*/ void sys_err(const char* str){perror(str);exit(1); }int main(int argc, char *argv[])){int client_fd=0;int ret=0;int num=0;int cnt=10;char buf[BUFSIZ];//connect的参数2填入服务器的文件描述符!struct sockaddr_in serv_addr;serv_addr.sin_family=AF_INET;serv_addr.sin_port=htons(SERV_PORT);// 本地字节序(string IP) ---> 网络字节序inet_pton(AF_INET,"127.0.0.1",(void*)&serv_addr.sin_addr.s_addr);/*1. 创建socket():客户端直接创建用于连接的套接字即可*/client_fd=socket(AF_INET,SOCK_STREAM,0);if(client_fd==-1)sys_err("socket error");/*2. connect():将客户端套接字与服务器地址结构连接起来*/ret=connect(client_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));if(ret!=0)sys_err("connect error");//业务逻辑while(--cnt){//3. write() 写数据到 socketwrite(client_fd,"fuckyou\n",8);//4. read() 读转换后的数据。num=read(client_fd,buf,sizeof(buf));//5. 显示读取结果write(STDOUT_FILENO,buf,num);sleep(1);}//6. close()close(client_fd);return 0; }
相关文章:
Linux网络编程:Socket套接字编程(Server服务器 Client客户端)
文章目录: 一:定义和流程分析 1.定义 2.流程分析 3.网络字节序 二:相关函数 IP地址转换函数inet_pton inet_ntop(本地字节序 网络字节序) socket函数(创建一个套接字) bind函数(给socket绑定一个服务器地址结…...
Mac OS下应用Python+Selenium实现web自动化测试
在Mac环境下应用PythonSelenium实现web自动化测试 在这个过程中要注意两点: 1.在终端联网执行命令“sudo pip install –U selenium”如果失败了的话,可以尝试用命令“sudo easy_install selenium”来安装selenium; 2.安装好PyCharm后新建project&…...
每天一道leetcode:934. 最短的桥(图论中等广度优先遍历)
今日份题目: 给你一个大小为 n x n 的二元矩阵 grid ,其中 1 表示陆地,0 表示水域。 岛 是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连。grid 中 恰好存在两座岛 。 你可以将任意数量的 0 变为 1 &#…...
【学习日记】【FreeRTOS】FreeRTOS 移植到 STM32F103C8
前言 本文基于野火 FreeRTOS 教程,内容是关于 FreeRTOS 官方代码的移植的注意事项,并将野火例程中 STM32F103RC 代码移植到 STM32F103C8。 一、FreeRTOS V9.0.0 源码的获取 两个下载链接: 官 网 代码托管 二、源码文件夹内容简介 Source…...
Qt 屏幕偶发性失灵
项目场景: 基于NXP i.mx7的Qt应用层项目开发,通过goodix使用触摸屏,走i2c协议。 问题描述 触摸屏使用过程中意外卡死,现场分为多种: i2c总线传输错误,直观表现为触摸屏无效,任何与触摸屏挂接在同一总线上的i2c设备,均受到干扰,并且在传输过程中内核报错以下代码: G…...
如何在pycharm中指定GPU
如何在pycharm中指定GPU 作者:安静到无声 个人主页 目录 如何在pycharm中指定GPU打开编辑配置点击环境变量添加GPU配置信息推荐专栏在Pycharm运行程序的时候,有时候需要指定GPU,我们可以采用以下方式进行设置: 打开编辑配置 点击环境变量 添加GPU配置信息 添加名称:CU…...
C#判断字符串中有没有字母,正则表达式、IsLetter
要判断字符串中是否包含字母,可以使用正则表达式或者循环遍历字符串的方式。 方法一:使用正则表达式 using System.Text.RegularExpressions;string input "Hello123"; bool containsLetter Regex.IsMatch(input, "[a-zA-Z]");上…...
Jtti:Ubuntu怎么限制指定端口和IP访问
在 Ubuntu 系统中,可以使用防火墙规则来限制特定的端口和IP访问。常用的防火墙管理工具是 iptables,以下是使用 iptables 来限制指定端口和IP访问的步骤: 安装 iptables: 如果系统中没有安装 iptables,可以使用以下命…...
机器学习/深度学习需要掌握的linux基础命令
很多深度学习/机器学习/数据分析等领域(或者说大多数在Python环境下进行操作的领域)的初学者入门时是在Windows上进行学习,也得益于如Anaconda等工具把环境管理做的如此友善 但如果想在该领域继续深耕,一定会与Linux操作系统打交…...
C++11 std::async推荐使用 std::launch::async 模式
async真假多线程 std::launch::async真多线程 std::launch::async | std::launch::deferred可能多线程 std::launch::deferred假多线程 枚举变量说明 枚举定义 enum class launch {async 1, // 0b1deferred 2, // 0b10any async | def…...
没有使用springboot 单独使用spring-boot-starter-logging
如果您不使用Spring Boot框架,但想单独使用Spring Boot Starter Logging,您可以按照以下步骤进行: 1. 添加Maven依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boo…...
创建Azure资源锁
锁的介绍 在Azure中,资源锁是一种用于保护订阅、资源组或者单个资源的机制。它可以防止对受锁定的资源进行删除或修改操作,帮助确保资源的连续可用性和安全性。 Azure中的资源锁可以分为两种类型: 删除锁(CanNotDelete…...
卷积神经网络教程 (CNN) – 使用 TensorFlow 在 Python 中开发图像分类器
在这篇博客中,让我们讨论什么是卷积神经网络 (CNN) 以及 卷积神经网络背后的架构——旨在解决 图像识别系统和分类问题。 卷积神经网络在图像和视频识别、推荐系统和自然语言处理方面有着广泛的应用。 目录 计算机如何读取图像? 为什么不是全连接网络?...
MyBatis XML映射处理CLOB和BLOB类型
Mybatis的MapperXML映射文件应该处理数据库字段类型为CLOB和BLOB类型的数据呢?首先我们先看下CLOB和BLOB这两种数据类型的介绍。 介绍 使用Mybatis时涉及到两种特殊类型的处理,分别是Blob(Binary Large Object)和Clob࿰…...
FPGA_学习_14_第一个自写模块的感悟和ila在线调试教程与技巧(寻找APD的击穿偏压)
前一篇博客我们提到了,如果要使用算法找到Vbr,通过寻找APD采集信号的噪声方差的剧变点去寻找Vbr是一个不错的方式。此功能的第一步是在FPGA中实现方差的计算,这个我们已经在上一篇博客中实现了。 继上一篇博客之后,感觉过了很久了…...
【2023新教程】树莓派定时自动拍照并上传腾讯云对象存储COS
1 换源 仅适用于Release date: May 3rd 2023、Debian version: 11 (bullseye)这个树莓派OS版本,其他版本不保证有效。 首先使用如下命令,查看自己树莓派的架构。 uname -a结果如下: 如果红圈处显示为aarch64,使用命令sudo na…...
校企合作谋发展 合作共赢谱新篇|云畅科技与湖南民族职业学院签订校企合作协议
产业是经济发展的重要引擎,人才是产业发展的重要资源。为积极探索软件人才培育新路径,共商政产学研协同新机制,8月8日,云畅科技与湖南省民族职业学院教育技术学院软件技术专业签订校企合作协议。 会上,学院副校长王志平…...
vue技术学习
vue快速入门 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>vue快速入门</title> </head> <body> <!--老师解读 1. div元素不是必须的,也可以是其它元素࿰…...
基于空间的图卷积神经网络:GNN
目录 欧氏空间中神经网络发挥巨大最作用,DNA,知识图谱三维或者多维空间不行 邻接矩阵实现图结构的矩阵化表示:造梦师 局和操作实现层内消息传递:带线的连接机传递消息 GCN通过邻域聚合实现特征提取 SVM支持向量机 编辑 硬分…...
.net core发布到IIS上出现 HTTP 错误 500.19
1.检查.net core 环境运行环境是否安装完成,类似如下环境 2.IIS是否安装全 本次原因就是IIS未安装全导致的 按照网上说的手动重启iis(iisreset)也不行...
01_Redis单线程与多线程
01——Redis单线程与多线程 一、Redis是单线程还是多线程 在谈Redis的单线程或多线程时,需要根据版本来区分。 在redis 3.x之前,redis是单线程的从redis 4.x开始,redis引入多线程。处理客户端请求时,使用单线程;在异…...
机器学习——随机森林【手动代码】
随机森林这个内容,是目前来说。。。最最最简单,最好理解,应该也是最好实现的了!!! 先挖坑,慢慢填 随机森林,这个名字取得,果然深得该算法的核心精髓,既随机&a…...
Vue 2 处理边界情况
访问元素和组件 通过Vue 2 组件基础一文的学习,我们知道组件之间可以通过传递props或事件来进行通信。 但在一些情况下,我们使用下面的方法将更有用。 1.访问根实例 根实例可通过this.$root获取。 我们在所有子组件中都可以像上面那样访问根实例&…...
写一个mysql 正则表达式,每三个img标签图片后面添加<hr>
你可以使用MySQL的REGEXP_REPLACE函数来实现这个需求。下面是一个示例的正则表达式和SQL语句: sql UPDATE your_table SET your_column REGEXP_REPLACE(your_column, (<img[^>]*>){3}, $0<hr>) WHERE your_column REGEXP (<img[^>]*>){3}…...
Spring MVC异常处理
Spring MVC异常处理 Spring MVC异常处理机制HandlerExceptionResolver的实现类DefaultHandlerExceptionResolver实现类DefaultHandlerExceptionResolver 在Controller的请求处理方法中手动使用try…catch块捕捉异常,当捕捉到指定的异常时,系统返回对应的…...
Centos7安装docker后默认开启docker0的网卡|卸载默认网卡
docker实战(一):centos7 yum安装docker docker实战(二):基础命令篇 docker实战(三):docker网络模式(超详细) docker实战(四):docker架构原理 docker实战(五):docker镜像及仓库配置 docker实战(六):docker 网络及数据卷设置 docker实战(七):docker 性质及版本选择 认知升…...
04_Redis与mysql数据双写一致性案例
04——redis与mysql数据双写一致性 一、canal 是什么 canal[ka’nel,中文翻译为水道/管道/沟渠/运河,主要用途是用于MySQL数据库增量日志数据的订阅、消费和解析,是阿里巴巴开发并开源的,采用Java语言开发; 历史背景是早期阿里巴巴因为杭州和…...
vue的开发者工具下载『保姆级别』
1.先进官网 极简插件_Chrome扩展插件商店_优质crx应用下载 (zzzmh.cn) 2.搜索vue devtools,点击进去 3.下载插件 4.下载到文件下你自己的文件下:我的是下载到E盘下。 5.压缩到当前目录下 6.电脑进入拓展程序(不同的浏览器操作不同ÿ…...
vue的scrollTop手机环境设置值失效,本地正常可以赋值
获取div盒子ref或者document获取都行 监听方法 一定要加this.$nexttick,在本地测试只用nexttick是没有问题的,但是到手机测试就不行了,原因是因为手机渲染比本地更快,所以结合setTimeout使用 如果有更好的处理方法,恳请大佬指点一…...
[前端系列第7弹]Vue:一个渐进式的 JavaScript 框架
Vue 是一个用于构建用户界面的 JavaScript 框架,它具有以下特点: 渐进式:Vue 可以根据不同的使用场景,灵活地选择使用库或者框架的方式,从而实现渐进式的开发。响应式:Vue 通过数据绑定和虚拟 DOM 技术&am…...
简约网站模板/app怎么开发出来的
“便笺”是Win10里内置的一项小功能,不过很多人对它并不了解。其实Win10的“便笺”(Sticky Notes),无论在颜值还是功能性方面,都可以堪称同类软件中的佼佼者。尤其是1809版之后的便笺3.0,更是融入了很多新功能,妥妥的记…...
郑州百度网站优化/长沙网站设计
List的有用实现1.ArrayList2.LinkedList3.Vector4.Stack讨论1:底层机制(牵扯到的数据结构的知识请读者自行复习)ArrayList与Vector都是基于数组实现的,这就说明ArrayList与Vector适合做遍历而不适合做频繁的插入和删除。LinkedList是基于链表实现的&…...
哈尔滨做网站需要多少钱/网络营销策略的制定
在Java应用中进行集合对象间的转换是非常常见的事情,有时候在处理某些任务时选择一种好的数据结构往往会起到事半功倍的作用,因此熟悉每种数据结构并知道其特点对于程序员来说是非常重要的,而只知道这些是不够的,有时候你需要一个…...
知名网络公司有哪些/济宁seo推广
先打出nand表0 nand 011 nand 100 nand 111 nand 01容易发现(!a)a nand a然后(a&b)!(a nand b)然后(a|b)!((!a)&(!b))然后(a^b)(a|b)&(a nand b)所以通过nand我们可以实现任意一种位运算所以每一位我们想得到0/1都是可以的按道理[L,R]中符合位数要求的数都能得到然…...
廊坊做网站的电话/今日热点头条新闻
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow...
wordpress多站点独立域名/色盲测试图动物
如图所示,昨天晚上点了那个Download按钮,下载Fedora31,下载完成后提示要重启安装。重启之后就黑屏了,一大串白色的字: alloc magic is broken at 0xXXXX 启动不了系统,昨天晚上太晚了就没继续弄了&#x…...