• 前言
  • 在学完不够全面的Linux操作系统编程后(这也意味着我后期也要不断学习,这也符合我活到老学到老的人生观点),需要以一些项目来检测自己的所学,毕竟实践见真章。

    所以在今后的几天里,我将以无界面聊天室为例子,来以我个人查阅相关资料后总结并介绍所用到的知识点,来以作为巩固与加强。(本人刚刚入门不久,但勤奋爱学,较为聪慧(本人自封,见笑了),如有错误,望见谅与通知改正)同时,我也会根据相应进度与情况来更新我的简书。接下来就进入正题吧。

    一、确定无界面聊天室的大概功能。

    我以当今流行的几个聊天软件为参考,大概先确定和聊天相关的一些功能。

    Linux 环境下的简易聊天室,采用C/S模型,实现多客户端之间的稳定数据传输。

    登陆注册账号,登陆时密码不会显

    好友管理

    a. 查看好友列表(不同颜色代表不同的状态)

    b. 添加好友

    c. 删除好友

    d. 屏蔽好友

    群管理

    a. 查看所加群,查看群中成员

    b. 创建群

    c. 加群

    d. 退群

    e. 解散群

    f. 设置管理员

    g. 踢人

    聊天通讯

    a. 私聊

    b. 群聊

    c. 查看聊天记录

    离线传输

    a. 离线消息

    b. 离线文件

    传送文件

    容错处理

    对服务器要求

    a. 面对同时大量的客户端发送连接与数据时,服务器能正常处理

    b. 客户端的意外退出,不会导致服务器退出

    c. 数据能够正确接收和发送

    二、基于功能来理顺代码实现大概思路。

    登陆、注册账号

    首先注册账号,然后才可以谈登录一说,所以我们先实现注册账号。但思考一下,这个用户账号的信息应该需要属性呢?(成员变量),不如先创建一个用户结构体,先加入一些用得着的变量,如果在之后需要增、删、用户的属性,直接对成员变量修改就行,并且也可以一目了然的确定用户的属性有哪些。就以当前注册、登陆为目的的属性并参考一些流行的聊天软件,我们要需要三个成员变量,用户名、账号、密码。

    struct Usr{char name[20];char account[10];char password[16];}

    注册的时候我们可以先输入用户名,然后自动分配账号,之后手动设置密码。设置密码的时

    mysql> use easytalk
    Database changed
    mysql> create table usr(name VARCHAR(20),account VARCHAR(10),password VARCHAR(16),PRIMARY KEY(account));
    Query OK, 0 rows affected (0.01 sec)

    候需要二次核验密码,以减少用户输入密码后所记住的密码与输入的不一致或者忘记密码情况。如果用户输入用户名和密码格式不对会被提示重新注册,有三次连续机会。当错误操作达到三次是,就跳出注册操作,进入主界面。如果注册操作成功,将注册信息存到mysql数据库里面

    (Linux本身并不带有Mysql,需要手动下载,在Ubuntu终端界面输入下面代码即可)

  •     sudo apt-get install mysql-server     //安装mysql

    可以提前创建一个easytalk的数据库

  • mysql> create database easytalk;
    Query OK, 1 row affected (0.02 sec)

    (database),然后在use(使用)这个database,之后用create语句创建一个usr的一个表,里面来存放用户的三个成员变量,name、account、password。我们在插入到数据表时,应该设置一个主键,那就是账号,用户的账号不能相同,但是用户名可以相同。

    mysql> use easytalk
    Database changed
    mysql> create table usr(name VARCHAR(20),account VARCHAR(10),password VARCHAR(16),PRIMARY KEY(account));
    Query OK, 0 rows affected (0.01 sec)
  • 登陆的时候我们需要输入账号和密码,然后查询数据库,能查询出来相关的账号密码,那就允许登陆。

    下面为主要代码部分

    声明用到的全局变量和将要马上用到的全局变量

  • MYSQL mysql;
    MYSQL *pmysql=NULL;
    MYSQL_RES *res=NULL;
    char slc[1024]="";  //全局变量用来存放查询语句的字符串
    unsigned int num_fields;struct sockaddr_in ser_addr,cli_addr;
    int sockfd=0;
    char str[MAXSIZE]={0};
    char buf[MAXSIZE]={0};
    pthread_t thread;

    先要连接下数据库

  • 101 int InitDB()
    102 {
    103         pmysql=mysql_init(&mysql);
    104         //mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
    105         //mysql_options(&mysql,MYSQL_INIT_COMMAND,"SET autocommit=1");
    106
    107         pmysql=mysql_real_connect(&mysql,       //数据库连接处理数据结构,如同FILE*
    108                         "localhost",   //MySQL服务器运行的主机名
    109                         "root",   //MySQL服务端提供的用户名
    110                         "0", //MySQL服务端提供的用户密码,我的数据库没密码,所以0就可以了,然后管理员模式执行代码
    111                         "easytalk",     //MySQL连接时指定连接到的数据库
    112                         0,  //端口号
    113                         NULL,//指定为套接字或者命名管道
    114                         0);//标志,通常为0
    115         //printf("mysql_real_connect success\n");
    116
    117 }
    

    创建一个建议的登录界面

  • 156 void Window()                           //      用户进入用户端界面
    157 {
    158         printf("/       ********************************************************************************************            /\n");
    159         if(Loggingstatus==0)
    160         {
    161                 printf("/       ****    欢迎进入easytalk                当前为未登陆状态                            ***    *****        /\n");
    162         }
    163         else
    164         {
    165                 printf("/       ****    欢迎用户%-20s    当前为已登陆状态                            ********        /\    n",USR.name);
    166
    167         }
    168         printf("/       ****    请输入你想操作的操作码                                                      ********            /\n");
    169         printf("/       ****    0.退出                                                                      ********            /\n");
    170         printf("/       ****    1.注册账号                                                                  ********            /\n");
    171         printf("/       ****    2.登陆账号                                                                  ********            /\n");
    172         printf("/       ****    3.退出当前登陆                                                              ********            /\n");
    173         printf("/       ********************************************************************************************            /\n");
    174 }
    

    下面为注册账号的代码,其中需要规定用户名和密码的格式,同时也需要二次校验密码。最后添加到数据库,并同时为用户创建一个表,用户表我们暂时存放好友列,群列表和屏蔽好友列表三个成员。

  • 175 int Register()
    176 {
    177         char nm[1024]={0};
    178         char ac[1024]={0};
    179         char ps1[1024]={0};
    180         char ps2[1024]={0};
    181         int count1=3;
    182         int count2=3;
    183         int count3=3;
    184         int tmprand=0;
    185         int len=0;
    186         int cs=0;
    187         int aclen=0;    //scanf的返回值,错误返回-1
    188         int row=0;
    189         srand((unsigned)time(NULL));
    190         printf("创建账号需要用户名,账号,密码,其中用户名和密码手动输入,账号位随机分配8-10位\n");
    191 a:
    192         printf("请输入用户名\n");
    193         cs=scanf("%s",nm);
    194         len=strlen(nm);
    195         if((cs==-1)||(len>20)||(len<8))//输入函数执行错误或者用户名长度不在8-20
    196         {
    197                 count1--;
    198                 if(count1==0)
    199                 {
    200                         printf("输入用户名格式错误三次,即将退出注册功能\n");
    201                         return -1;
    202                 }
    203                 printf("输入格式错误,请重试,你还剩余%d次机会,当机会为零将自动退出注册系统\n",count1);
    204                 goto a;
    205         }
    206 b:
    207         printf("请输入密码\n");
    208         cs=scanf("%s",ps1);
    209         len=strlen(ps1);
    210         if((cs==-1)||(len>16)||(len<8))//第一次输入密码输入函数错误错误或者密码不在8-16位
    211         {
    212                 count2--;
    213                 if(count2==0)
    214                 {
    215                         printf("输入密码格式错误三次,即将退出注册功能\n");
    216                         return -2;
    217                 }
    218                 printf("输入密码格式错误,请重试,你还剩余%d次机会,当机会为0将自动退出注册系统\n",count2);
    219                 goto b;
    220         }
    221         printf("请再次输入密码\n");
    222         cs=scanf("%s",ps2);
    223         len=strlen(ps2);
    224         if((cs==-1)||(strcmp(ps1,ps2)!=0)) //两次密码输入不一样或者输入错误
    225         {
    226                 count2--;
    227                 if(count2==0)
    228                 {
    229                         printf("输入密码格式错误三次,即将退出注册功能\n");
    230                         return -3;
    231                 }
    232                 printf("两次输入的密码不一致,请重试,你还剩余%d次机会,当机会为0将自动退出注册系统\n",count2);
    233                 goto b;
    234         }
    235         do
    236         {
    237                 aclen=rand()%3+8;
    238                 //printf("aclen%d\n",aclen);
    239                 int arr[aclen];
    240                 for(int i=0;i<aclen;i++)
    241                 {
    242                         int x=0;
    243                         if(i==0)
    244                         {
    245                                 arr[i]=rand()%9+1+48;
    246                         }
    247                         else
    248                         {
    249                                 arr[i]=rand()%10+48;
    250
    251                         }
    252                         ac[i]=(char)arr[i];
    253                 }
    254                 sprintf(slc,"select * from usr where account='%s'",ac);
    255                 int b=mysql_real_query(&mysql,slc,strlen(slc));
    256                 if(b!=0)
    257                 {
    258                         //printf("检测账号\n");
    259                         perror("sql_real_query");
    260                 }
    261                 else
    262                 {
    263                         //printf("%d\n",b);
    264                 }
    265                 res=mysql_store_result(&mysql);
    266                 row=mysql_num_rows(res);
    267                 //if(row==1)
    268                 mysql_free_result(res);
    269
    270         }while(row==1);  //do  while 检测自动分配的账号是否重复,重复的话重新分配账号
    271         printf("分配的账号为%s\n",ac);
    272         sprintf(slc,"insert into usr values('%s','%s','%s')",nm,ac,ps1);
    273         //printf("%s\n",slc);
    274         int r1=mysql_real_query(&mysql,slc,strlen(slc));//将注册的账号信息插入到数据表
    275         int r2=0;
    276         //res=mysql_store_result(res);
    277         //mysql_free_result(res);
    278
    279         //printf("insert%d\n",r1);
    280         if(r1!=0)
    281         {
    282
    283                 perror("mysql_real_query");
    284         }
    285         else
    286         {
    287                 char slc1[1024]="create table ";
    288                 strcat(slc1,nm);
    289                 strcat(slc1,ac);
    290                 strcat(slc1,"(friends VARCHAR(20),sheilfriends VARCHAR(20),talkgroup VARCHAR(20))");
    291                 //printf("%s\n",slc1);
    292                 int slc1len=0;
    293                 int i=0;
    294                 while(((slc1[i]=='\0')&&(slc[i+1]=='\0')==0))
    295                 {
    296                         slc1len++;
    297                         i++;
    298
    299                 }
    300                 //slc1len=strlen(slc1);
    301                 //printf("slc1len:%d",slc1len);
    302                 //r2=mysql_real_query(&mysql,slc1,slc1len);//以用户名和账号共同创建个数据表,并储存好友列表,屏蔽好友列表和群列表
    303                 r2=mysql_real_query(&mysql,slc1,strlen(slc1));//以用户名和账号共同创建个数据表,并储存好友列表,屏蔽好友列表和群列表
    304                 //res=mysql_store_result(res);
    305                 //mysql_free_result(res);
    306         }
    307         /*if(r2!=0)
    308           {
    309           perror("mysql_real_query");
    310           }*/
    311         //printf("%d\n",r2);
    312         if(r2!=0)
    313         {
    314                 perror("mysql_real_query");
    315
    316         }
    317         if((r1==0)&&(r2==0))
    318         {
    319                 printf("注册成功\n");
    320         }
    321         else
    322         {
    323                 printf("注册失败\n");
    324         }
    325         return 0;
    326
    327
    328 }

    然后为登录的函数,需要查询数据库比对,然后更改当前进程登录用户信息。

  • 329 int Login()
    330 {
    331         char ac[10]={0};
    332         char ps[16]={0};
    333         char slc[1024]="select * from usr where(account='";
    334         printf("你已进入登陆系统\n");
    335         printf("请输入你的账号\n");
    336         scanf("%s",ac);
    337         strncat(slc,ac,strlen(ac));
    338         printf("请输入你的密码\n");
    339         scanf("%s",ps);
    340         strcat(slc,"' AND password='");
    341         strncat(slc,ps,strlen(ps));
    342         strcat(slc,"')");
    343         int ret=mysql_real_query(&mysql,slc,strlen(slc));
    344         res=mysql_store_result(&mysql);
    345         int row=mysql_num_rows(res);
    346         if(row==1)
    347         {
    348                 unsigned long *lenths=0;
    349                 unsigned int i=0;
    350                 MYSQL_ROW fetchrow;
    351                 //num_fields = mysql_num_fields(result);
    352                 fetchrow=mysql_fetch_row(res);
    353                 strncpy(USR.name,fetchrow[0],strlen(fetchrow[0])); //修改当前程序用户信息,以便后续使用
    354                 strncpy(USR.account,ac,strlen(ac));
    355                 strncpy(USR.password,ps,strlen(ps));
    356                 Loggingstatus=1;
    357                 printf("登陆成功\n");
    358                 return 0;
    359         }
    360         else
    361         {
    362                 printf("登陆失败\n");
    363         }
    364}
    

    上面的代码为暂时的主要代码,下面为我现在进程的全部代码,有些代码没有在上面列出,但是今后也会一一介绍。

    #include<stdio.h>
    #include<string.h>
    #include <stdlib.h>
    #include <mysql/mysql.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <poll.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #define handle_error_en(en, msg) \do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)#define MAXSIZE 1024
    struct Usr{char name[20];char account[10];char password[16];
    }USR,Tmpusr;
    int Loggingstatus=0;   //设置一个登陆标志,0未位有人登陆,1为已登录登陆;
    MYSQL mysql;
    MYSQL *pmysql=NULL;
    MYSQL_RES *res=NULL;
    char slc[1024]="";  //全局变量用来存放查询语句的字符串
    unsigned int num_fields;struct sockaddr_in ser_addr,cli_addr;
    int sockfd=0;
    char str[MAXSIZE]={0};
    char buf[MAXSIZE]={0};
    pthread_t thread;int InitDB();
    int Register();
    int InitSocket(char const* argv1,char const* argv2);
    void Window();
    int Login();int main(int argc,char const* argv[])
    {int c=0;InitDB();InitSocket(argv[1],argv[2]);while(c!=-1){Window();scanf("%d",&c);switch(c){case 0:c=-1;break;case 1:Register();break;case 2:Login();break;case 3:Loggingstatus=0;strcpy(USR.name," ");strcpy(USR.account," ");strcpy(USR.password," ");break;default:printf("请输入争取的操作玛\n");break;}}mysql_close(&mysql);return 0;}
    /*****************************初始化数据库函数,连接到数据库easytalk** ************************/int InitSocket(char const* argv1,char const* argv2)
    {int port = atoi(argv1);int sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd==-1){handle_error_en(sockfd,"socket");}ser_addr.sin_family=AF_INET;ser_addr.sin_port=htons(port);ser_addr.sin_addr.s_addr=inet_addr(argv2);socklen_t addrlen=sizeof(ser_addr);int ret=connect(sockfd,(struct sockaddr *)&ser_addr,addrlen);}int InitDB()
    { pmysql=mysql_init(&mysql);//mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);//mysql_options(&mysql,MYSQL_INIT_COMMAND,"SET autocommit=1");pmysql=mysql_real_connect(&mysql,       //数据库连接处理数据结构,如同FILE*"localhost",   //MySQL服务器运行的主机名"root",   //MySQL服务端提供的用户名"0", //MySQL服务端提供的用户密码"easytalk",     //MySQL连接时指定连接到的数据库0,  //端口号NULL,//指定为套接字或者命名管道0);//标志,通常为0//printf("mysql_real_connect success\n");}
    /********************************注册函数,并将用户的账号信息储存到数据库** **************************/
    void *ReadMsg(void * arg)
    {int num=0;static char buf_r[MAXSIZE]={0};int newfd=*(int *)arg;while(1){num=recv(newfd,buf_r,MAXSIZE,0);if(strncmp(buf_r,"quit",4)==0){exit(0);}printf("recv msg:%s\n",buf_r);}
    }
    void *SendMsg(void * arg)
    {int num=0;static char buf_s[MAXSIZE]={0};int newfd=*(int *)arg;while(1){num=send(newfd,buf_s,MAXSIZE,0);if(strncmp(buf_s,"quit",4)==0){exit(0);}printf("send msg:%s\n",buf_s);}
    }void Window()                           //      用户进入用户端界面
    {printf("/       ********************************************************************************************        /\n");if(Loggingstatus==0){printf("/       ****    欢迎进入easytalk                当前为未登陆状态                            ********        /\n");}else{printf("/       ****    欢迎用户%-20s    当前为已登陆状态                            ********        /\n",USR.name);}printf("/       ****    请输入你想操作的操作码                                                      ********        /\n");printf("/       ****    0.退出                                                                      ********        /\n");printf("/       ****    1.注册账号                                                                  ********        /\n");printf("/       ****    2.登陆账号                                                                  ********        /\n");printf("/       ****    3.退出当前登陆                                                              ********        /\n");printf("/       ********************************************************************************************        /\n");
    }
    int Register()
    {char nm[1024]={0};char ac[1024]={0};char ps1[1024]={0};char ps2[1024]={0};int count1=3;int count2=3;int count3=3;int tmprand=0;int len=0;int cs=0; int aclen=0; //scanf的返回值,错误返回-1int row=0;srand((unsigned)time(NULL));printf("创建账号需要用户名,账号,密码,其中用户名和密码手动输入,账号位随机分配8-10位\n");
    a:printf("请输入用户名\n");cs=scanf("%s",nm);len=strlen(nm);if((cs==-1)||(len>20)||(len<8))//输入函数执行错误或者用户名长度不在8-20{count1--;if(count1==0){printf("输入用户名格式错误三次,即将退出注册功能\n");return -1;}printf("输入格式错误,请重试,你还剩余%d次机会,当机会为零将自动退出注册系统\n",count1);goto a;}
    b:printf("请输入密码\n");cs=scanf("%s",ps1);len=strlen(ps1);if((cs==-1)||(len>16)||(len<8))//第一次输入密码输入函数错误错误或者密码不在8-16位{count2--;if(count2==0){printf("输入密码格式错误三次,即将退出注册功能\n");return -2;}printf("输入密码格式错误,请重试,你还剩余%d次机会,当机会为0将自动退出注册系统\n",count2);goto b;}printf("请再次输入密码\n");cs=scanf("%s",ps2);len=strlen(ps2);if((cs==-1)||(strcmp(ps1,ps2)!=0)) //两次密码输入不一样或者输入错误{count2--;if(count2==0){printf("输入密码格式错误三次,即将退出注册功能\n");return -3;}printf("两次输入的密码不一致,请重试,你还剩余%d次机会,当机会为0将自动退出注册系统\n",count2);goto b;}do{aclen=rand()%3+8;//printf("aclen%d\n",aclen);int arr[aclen];for(int i=0;i<aclen;i++){int x=0;if(i==0){arr[i]=rand()%9+1+48;}else{arr[i]=rand()%10+48;}ac[i]=(char)arr[i];}sprintf(slc,"select * from usr where account='%s'",ac);int b=mysql_real_query(&mysql,slc,strlen(slc));if(b!=0){//printf("检测账号\n");perror("sql_real_query");}else{//printf("%d\n",b);}res=mysql_store_result(&mysql);row=mysql_num_rows(res);//if(row==1)mysql_free_result(res);}while(row==1);  //do  while 检测自动分配的账号是否重复,重复的话重新分配账号printf("分配的账号为%s\n",ac);sprintf(slc,"insert into usr values('%s','%s','%s')",nm,ac,ps1);//printf("%s\n",slc);int r1=mysql_real_query(&mysql,slc,strlen(slc));//将注册的账号信息插入到数据表int r2=0;//res=mysql_store_result(res);//mysql_free_result(res);//printf("insert%d\n",r1);if(r1!=0){perror("mysql_real_query");}else{char slc1[1024]="create table ";strcat(slc1,nm);strcat(slc1,ac);strcat(slc1,"(friends VARCHAR(20),sheilfriends VARCHAR(20),talkgroup VARCHAR(20))");//printf("%s\n",slc1);int slc1len=0;int i=0;while(((slc1[i]=='\0')&&(slc[i+1]=='\0')==0)){slc1len++;i++;}//slc1len=strlen(slc1);//printf("slc1len:%d",slc1len);//r2=mysql_real_query(&mysql,slc1,slc1len);//以用户名和账号共同创建个数据表,并储存好友列表,屏蔽好友列表和群列表r2=mysql_real_query(&mysql,slc1,strlen(slc1));//以用户名和账号共同创建个数据表,并储存好友列表,屏蔽好友列表和群列表//res=mysql_store_result(res);//mysql_free_result(res);}/*if(r2!=0){perror("mysql_real_query");}*///printf("%d\n",r2);if(r2!=0){perror("mysql_real_query");}if((r1==0)&&(r2==0)){printf("注册成功\n");}else{printf("注册失败\n");}return 0;}
    int Login()
    {char ac[10]={0};char ps[16]={0};char slc[1024]="select * from usr where(account='";printf("你已进入登陆系统\n");printf("请输入你的账号\n");scanf("%s",ac);strncat(slc,ac,strlen(ac));printf("请输入你的密码\n");scanf("%s",ps);strcat(slc,"' AND password='");strncat(slc,ps,strlen(ps));strcat(slc,"')");int ret=mysql_real_query(&mysql,slc,strlen(slc));res=mysql_store_result(&mysql);int row=mysql_num_rows(res);if(row==1){unsigned long *lenths=0;unsigned int i=0;MYSQL_ROW fetchrow;//num_fields = mysql_num_fields(result);fetchrow=mysql_fetch_row(res);strncpy(USR.name,fetchrow[0],strlen(fetchrow[0])); //修改当前程序用户信息,以便后续使用strncpy(USR.account,ac,strlen(ac));strncpy(USR.password,ps,strlen(ps));Loggingstatus=1;printf("登陆成功\n");return 0;   }else{printf("登陆失败\n");}}
    

    最后需要注意的是,这个只是客户端代码,我并没有在上面添加服务端的,但是运行这些代码时无上大雅,因为主要这篇就是来搞注册和登录的。编译时需要链接mysqlclient 及pthead,虽然线程功能没让他具体实现,但是要用得着之后,所以编译时后面跟随代码-lmysqlclient和-lphread

    ,然后已管理员模式运行可执行文件,执行时可直接执行,需要添加参数,一个是端口号,一个是IP地址。你可以运行时添加下面代码

  • sudo ./clie 8888 127.0.0.1
    

    中间有些算法不算佳,因为中间调试的工程中,感觉有的算法可能更加,但是一直报错,甚至我调试半天,最后还是用了写较长的代码来实现。我的代码只是思路的参考和一些函数的具体应用,希望你们有哪些疑惑可以留言或者上网搜索,这样可以更加容易的进步。

超详细:实现过程-Linux 环境下的简易聊天室,采用CS模型,实现多客户端之间的稳定数据传输。--注册和登录(但之后会连续更新内容,直至全部实现)相关推荐

  1. 2021.10.02超详细实现过程-Linux 环境下的简易聊天室,采用CS模型,实现多客户端之间的稳定数据传输。(添加好友,删除好友、屏蔽好友、查看好友列表(针对数据库的操作))

    这次主要对加好友.删除好友.屏蔽好友.查看好友列表功能(单纯的基于数据库操作),并且也对之前的代码做了部分的改动,为中间涉及全局变量问题. 对之前的改动(主要): 其中对结构体进行了改动和结构体全局变 ...

  2. Linux环境下——C语言聊天室项目

    由于使用了多线程操作,客户端进入程序后请先随便注册一次用户后再进行使用. 本程序默认第一个用户即ID为1的用户为超级管理员. 由于线程阻塞,最后的踢人操作有阻塞,需要在被踢出在线链表后手动下线. 看了 ...

  3. Linux环境下,通过shell脚本实现一键部署MySQL,并支持多种类型

    Linux环境下一键部署MySQL脚本,支持多种类型 前言 一.使用前须知 二.使用方法 三.shell脚本内容 总结 前言   MySQL是目前最流行的关系型数据库管理系统之一,属于 Oracle ...

  4. Linux环境下Python的安装过程

    Linux环境下Python的安装过程 前言 一般情况下,Linux都会预装 Python了,但是这个预装的Python版本一般都非常低,很多 Python的新特性都没有,必须重新安装新一点的版本,从 ...

  5. hp ux安装mysql5.1.56_详细讲解Linux环境下MySQL5.1安装步骤

    1.下载MySQL免安装版/二进制版软件(不用编译) 文件格式:MYSQL-VERSION-OS.tar.gz 2.创建MySQL组,建立MySQL用户并加入到mysql组中 (不同版本的Unix中, ...

  6. k8s简介以及linux环境下的详细安装步骤

    k8s简介以及linux环境下的详细安装步骤 k8s是Kubernetes的简称,Kubernetes中间有8个单词,所以叫k8s,就是这么简单粗暴. 我们可以看到docker的图标是鲨鱼,k8s的图 ...

  7. linux下的python安装,linux环境下的python安装过程

    一.下载python源码包 打开ubuntu下的shell终端,通过wget命令下载python源码包,如下图所示: wget https://www.python.org/ftp/python/3. ...

  8. Linux版本配置环境变量,如何linux环境下配置环境变量过程图解

    jdk下载地址: 在linux环境下的root同级目录下配置software目录 将下载好的jdk上传到software文件夹里面 (我使用的操作软件是) 到software这个目录下. 输入命令:c ...

  9. Linux 环境下php5.6,如何正确安装微软Mssql驱动--详细教程

    Linux 环境下,如何正确安装微软Mssql驱动 近日,由于公司业务的需要,需要用到PHP连接一个客户的Mssql服务器.于是,开始一番折腾之路.Baidu与Google之后,发现,网上说的各种方法 ...

最新文章

  1. Linux_SELinux使用
  2. 机器学习实战读书笔记(一)机器学习基础
  3. 洛谷P2698 [USACO12MAR]花盆Flowerpot
  4. SQLserver被js注入的全库替换SQL
  5. Spark-大规模数据处理计算引擎
  6. matplotlib导包
  7. 辽宁工业大学计算机复试经验,辽宁工业大学车辆工程考研经验
  8. 导入别的项目到我的eclipse上出现红色感叹号问题
  9. 吴恩达教授机器学习课程笔记【九】- k均值聚类算法
  10. pyhive ModuleNotFoundError: No module named ‘thrift‘
  11. C语言利用堆筛选前1000大元素
  12. 仿真软件测试基尔霍夫定律,标签:基尔霍夫定律
  13. TSP问题——GA(遗传算法)解法(附源代码)
  14. tp5微信公众号发送模板消息
  15. 转行学Java怎么样?Java培训机构有什么避雷的要点?
  16. 如何解锁CourseHero文档
  17. boot中jar包部署的方式读取classes下的文件
  18. 序列划分c语言,看懂了这些,你对缠论中的线段划分就基本掌握了!
  19. C语言上机报告例文,c语言上机实验报告_大一c语言上机实验报告_c语言实验报告怎么写...
  20. JS:来一盘紧张而又刺激的五子棋

热门文章

  1. cat6 万兆_CAT6以及CAT6A系统万兆测试方法
  2. windows server服务器性能监控
  3. 时间序列(time serie)分析系列之简介1
  4. python代码雨在桌面实现_今天七夕节,外面下着大雨,用Python的tkinter做一个下爱心雨的特效,发给妹子...
  5. java 类加载 apk_在Android的App中动态的加载Java类
  6. 这是最全的一篇!!!浏览器输入网址后发什么了什么?
  7. java jlabel对齐方式_怎么设置JLabel内容对齐方式
  8. [AHK]一键摘抄金句到Obsidian
  9. c语言中左移右移有什么作用,C语言中左移和右移运算符详细介绍
  10. Android DataBinding双向绑定原理