Linux下的Tcp通信项目范例【demo】

2023-05-16

一,适合阅读对象:2-4个月的初学者(C语言编程方向)

二,项目内容:

设计一个可以符合多用户进行线上查阅乐器的商城,要求可以多个用户查看,管理员可随时修改内容,普通用户仅可查看,需要相应密码权限操作。

三,项目需要的技术:

tcp(socket通信),IO多路复用,sqlite3数据库引用,makefile工程管理(已经说腻了的技术)

四,设计思路:

1,创建登录界面和注册界面。2,设计普通用户和管理员账户界面。3,设计界面功能。

注:正文内主要讲解登录和注册,其他的主讲思路,需要理解意思请详细查看。接下来开始讲解。

----------------------------------我是分割线--------------------------------------------------

一,创建登录界面和注册界面

思维路径(可能需要用到的技术):①创建管理用户账号密码的数据库。②输入密码时将数据库内容拉出来与用户输入内容做对比,正确进入,失败则退出。③因为主要是为了让用户进行查看,所以密码忘了重新再创建一个就行,不写找回密码(只是自己比较懒-,-)。【总头文件在最底下

①先来在服务器bin目录下定义用户信息数据库。为了简单好记,直接就如下(这条代码不重要,可以忽略,但是下面那个sqlite3数据库下载方式要记住):

create table code(username text primary not null,passwrod text);
//在数据库内部直接创建数据表code,定义关键元素一username(用户名),
//元素二(用户密码) .
//注意:此路径在命令行服务器(server)的运行文件目录(bin)下,
//我们创建数据库的名字sqlite3 code.db 

如果没有sqlite3数据库,建议去菜鸟教程下载,

下载完后请输入sudo apt-get install  libsqlite3-dev获取sqlite3库文件。

注意:这里是在命令行创建的用户信息数据库,如果有商家使用,则我们需要在注册时候服务器自动创建一个

②接下来要做的,就是写子函数让用户去注册密码。(有密码才能注册!)如下为【客户端】:

//函数功能,发送用户注册的账户密码信息至服务器
//参数1:参数为客户端socket文件描述符
//返回值:成功返回0 失败返回-1
int  creatpassword(int sock) //
{
char all[50]={0};//用来收录用户输入内容
printf("请输入您需要注册的账号与密码 格式【账号 密码#】\n");//此格式的目的是为了解析用户输入内容,就像输入门禁密码都要按#号一样,我们的规定是空格前为账号,空格后到#号为密码.
fgets(all,sizeof(all),stdin); //获取缓冲区内容
send(sock,all,sizeof(all),0); //发送信息至服务器
memset(all,0,sizeof(all));//
recv(sock,all,sizeof(all),0);//用来接收服务器若注册成功,发送的返回消息
if(strcmp(all,"注册成功")==0) {printf("注册成功,请退出程序重新进入\n");return 0;}
if(strcmp(all,"注册失败")==0) {printf("注册失败,请联系管理员查看\n");return 0;}
return 0;
}

下为服务器端注册密码子函数【服务器端 】

//函数功能,接收客户端发送的账号密码存储至数据库
//参数1:服务器监听socket接收到文件后,生成对应的文件描述符。参数2:用户输入的账户名
//参数3:用户输入的密码
//返回值:成功返回0 失败返回-1
int createuser(int i,char* username,char* password)
{
sqlite*db=NULL;//用来引导命令的数据库指针
char  sql[100]={0};//用来收纳放入账号密码至数据库的命令
int tc = sqlite3_open("yuequ.db",&db);if(tc<0)printf("注册数据库打开失败!\n");//打开数据库
int tp = sqlite3_exec(db,"create table if not exists code(username text primary key not null,password text)");//创建一个数据表存放用户账户密码,若存在则不会创建,不存在则新建
if(tp<0){printf("用户数据表创建异常!");return -1;}
int ts=sprintf(sql,"insert into code ('%s','%s')",username,passwrod); //存储用户输入的内容至用户数据表中
if(ts<0) {printf("用户数据存储失败!\n");return -1;}
rturn 0;
}

注册操作完成了,那至少我们要把需要传输的桥(tftp)搭起来,所以我们先创建一下需要的socket文件。

接下来为客户端socket创建【客户端】

//函数功能,客户端sock文件
//参数一,命令行输入服务器的IP 参数2,命令行输入服务器端口号
//返回值,成功返回socket文件描述符,失败返回-1 
int creatsock(argv[1],argv[2])
{
int fa = socket(AF_INET,SOCK_STREAM,0);if(a<0){printf("客户端套接字文件创建失败!\n");rturn -1;}

struct sockaddr_in FF;//定义客户端链接服务器时,需要用到结构体
FF.sin_familty=AF_INET;//赋值传输层协议给结构体family
FF.sin_add.s_addr = inet_addr(argv[1]);//将输入的IP从主机字节序转化为网络字节序,然后赋值给结构体
FF.sin_port= htons(atoi(argv[2]));//先将输入的端口号从字符串转为整形,再转化为网络字节序,赋值给结构体  两个都一样,我们输入时候都是主机字节序,不转化的话传过去服务器不认识
int fb=connect(socket,(struct sockaddr *)&FF,sizeof(FF));//与服务器进行链接
if(fb<0){printf("主机端尝试发送链接失败\n");return -1;}
return fa;
}

接下来为服务器端口的socket文件创建及接收绑定 【服务器端

//函数功能:实现与客户端的tcp链接
//参数1:需要绑定的Ip号 参数2:需要绑定的端口号
//返回值:成功返回socket文件描述符,失败返回-1
int tcp_server(argv[1],argv[2])
{
int ta=socket(AF_INET,SOCK_STREAM,0);//参数1:传输协议 参数2:流式套接字的标识符 参数3:与参数2组合使用以构成特殊协议。本项目不涉及,所以为0;
if(ta<0) {printf("服务器socket文件创建失败!\n");return -1;}
struct sockaddr_in BB;//用户服务器自身绑定时,识别的第二个参数
BB.sin_addr.s_addr = inet(argv[1]);
BB.sin_port = htons(atoi(argv[2]));
BB.sin_family = AF_INET;
int tb=bind(ta,(struct sockaddr*)&BB,sizeof(BB)); //操作系统规定第二个参结构体类型没有in,又规定结构体创建时必须有in,所以需要强行转换,以让操作系统识别到整个结构体。
if(tb<0){printf("绑定失败!\n");return -1;}
int tc=listen(ta,1024);//监听服务器是否有其他接入请求,最多可支持1024个客户端
if(tc<0) {printf("监听树立失败!\n");return -1;}
return ta;
}

③ 注册完成了,并且可以连接了,那是不是就是可以判断用户输入的密码是否正确呢? NO!NO!NO! 要知道我们要做的可是一个服务器同时接收多个客户端,现在我们只是仅仅可以监听出来1024个请求,但无法接起来,所以下一步,我们需要创建IO多路复用,获得多个客户端同时连接服务器的功能。具体如下【服务器端】:

int main{int argc,char *argv[]}
{
int Newfd=0; //用来接入新客户端的文件描述符
int tp = tcp_server(); //接收服务器自身的socket文件
struct sockaddr_in II; //用来接收客户端传递的结构体以搭建tftp桥梁
II.sin_family=AF_INET;
II.sin_addr.s_addr = inet_addr(argv[1]);
II.sin_port=htons(atoi(argv[2]));

fd_set table;fd_set temp;//创建两个套接字表格,以存放接入的客户端socket文件描述符及接听功能
fd_ZERO(&table); fd_ZERO(&temp);//腾空套接字表格内数据
fd_SET(tp,&table);//将初始的套接字描述符放到table表格内
while(1) //循环监听外部接入请求
{ 
temp = table;//将参照表格内数据放置动态表格
struct timeval tv;//建立未接入客户端时,服务器正常扫描一次运行的时间间隔
tv.tv_sec = 10;//结尾
tv.tv_usec=0;  //开始
 int ta = select(FD_SETSIZE,&temp,NULL,NULL,&tv);//每空十秒就将扫描一次temp表,共扫描1024个
//空位,FD_SETSIZE=1024;
if(ta<0) {printf("运转异常,多路复用IO创建失败!\n");return -1;}
if(ta==0){printf("程序运转中....\n");}
if(ta>0) //这个时候就来客户端请求了,但不知道是新客户端请求接入,还是旧客户端发送数据
{    
    for(int i= 0;i<FD_SETSIZE;i++)
     {
       if(FD_ISSET(i,&temp))  //扫描目前temp表有几个文件描述符,返回文件描述符的数字
         {
              if(i==tp)  //返回的数字和初始化的数字相等
            { 
                   int Newfd=connect(tp,(struct sockaddr *)&II,sizeof(II));
                   if(Newfd<0){printf(新客户端接入异常\n);}
    printf("客户端接入成功,IP为%s  ,端口号为%d\n",ntoa(II.sin_addr),ntohs(II.sin_prot));
                     FD_SET(Newfd,&table);//将新客户端文件描述符放到参照表里
            }
              else
               {
                 //填入运转子函数,发现接入的是旧客户端发送数据,就可以开始分析工作了
               }
         }
     }
}
}
}

做完上面这一步,那我们现在既可以多端互通,也可以正常链接了。

接下来就是解析我们上面说过的,用户链接上后开头发送了一个【账号空格密码#】的内容,我们需要解析,收到数据后,第一件是就是先去解析命令。所以无论发过来的是账号密码或者其他类型命令,都是以这个格式进行解析的。接下来我们来写入解析函数

④写入解析子函数,解析用户发过来的数据内容 【服务器端】(算法我就不解释了,大家自己看)

//函数功能,解析用户命令
//参数1,完整用户命令 
//参数2,外部引入的空缓存区,存放命令1 
//参数3,外部引入的空缓存2用来存放命令2
//返回值: 成功返回0 失败返回-1
int parcode(char *all,char *b,char*c)
{
   char *str=all;
	while(1)
	{
		if(*str==' ')
		{
			*cmd = 0;
			 str++;
			 break;
		}
		*cmd=*str;
	     cmd++;
		 str++;
	}
	while(1)
	{
		if(*str == '#')
		{
			*name = 0;
			break;
		}
		   *name=*str;
		   str++;
		   name++;
	}
	return 0;
}

⑤引入管理其他子函数的组长子函数,以方便所有子函数工作流程为: 获取数据->解析数据->对应操作子函数->发送用户端需要的内容【服务器端】如下思路版为:

//函数功能,管理所有子函数,使服务器其正常运转
//参数:从主函数里收纳的客户端socket描述,内含客户端发送的指令
//返回值:成功0,失败-1
int func(int i) 
{
   char all[50]={0};  //用以存放用户开头发送的数据 
   recv(i,all,sizeof(all),0);//用来接收用户发送的数据
   char a[20]={0}; char b[20]={0};  //分别存放用户解析数据后分出来的命令A 和命令B   
   parcode(all,a,b); //解析命令发送至a与b
   //解析完命令后,就可以开始操作了,根据发送的命令,去执行相应子函数即可。
   // 只举一个例子,刚开始我们发送了账号密码 所以发送账号密码之前我需要发送一个命令到
    服务器,然后进入存储密码的子函数,即上面的
                                int creatuser(char*all,char*username,char*password)
    所以开头客户端连接后就需要先发送一个命令让主函数解析,进入相应的子函数
    然后服务器子函数再次与客户端进行交互即可实现需求
   

}

可以看到服务器详细操作如下:【服务器端】

int func(int i)
{
	sqlite3 *db=NULL;char all[100]={0};char cmd[100]={0};char name[100]={0}; 
	char B[50]={0}; 
    char C[50]={0};   //用来接收账号密码
	memset(cmd,0,sizeof(cmd));
	memset(all,0,sizeof(all));
    int o =0;
	recv(i,all,sizeof(all),0);  if(signal(SIGPIPE,SIG_IGN)==SIG_ERR){return 0;}
	if(*all!=0)    //避免用户发送空文件导致异常数据,导致解析失败出现段错误关闭服务器
	{
	      while(o<100)//避免用户发送命令后没有添加#号,导致搜寻错引起段错误
		  {
			  if(all[o]!='#')
			  {
				  o++;
			  }
			  else if(all[o]=='#')
			  {
		       parsecode(all,cmd,name);//基础命令解析
	           printf("读取基础命令为%s\n",cmd);
				  break;
			  }
		  }
	}
	if(strncmp(cmd,"create",6)== 0)
	{  
		recv(i,B,sizeof(B),0);
		sleep(1);
		recv(i,C,sizeof(C),0);
		printf("创建的账号为%s  密码为%s\n",B,C);
		code(i,B,C); //这个code即是录入密码至数据库的子函数
		char NNN[100] ={0};
        strcpy(NNN,"账号密码录入成功");
		send(i,NNN,strlen(NNN),0);
		memset(B,0,sizeof(B));
		memset(C,0,sizeof(C));
	}
	else if(strncmp(cmd,"coming",6)==0)  //基础命令为用户需要输入密码进入程序
	{ 
		recv(i,B,sizeof(B),0); 
		sleep(1);
		recv(i,C,sizeof(C),0);
		int tc = sqlite3_open("./code.db",&db);
		if(tc<0)
		{
			perror("密码检测失败!\n");
		}
		char sql[100] = {0};
		sprintf(sql,"select *from code where username ='%s' and password ='%s' ",B,C);
		printf("%s\n",sql);
		char *nn=NULL;  
		sqlite3_exec(db,sql,CBcode,&i,&nn);  //这里的第三个参数为CBcode子函数,如果数据搜寻到发送的数据,则进入CBcode运转,未搜寻到则直接跳过sqlite3_exec函数 
		send(i,"账号密码不存在或出错!",40,0);//发送错误信息至客户端
		memset(B,0,sizeof(B)); //无论如何,上面的send都会被发送至客户端,所以成功了则客户端需要接收两次消息,失败了则接收一次。那么成功了则需要让客户端显示成功这一条收到的信息,隐藏失败的这一条。若失败了则直接打印失败就可以,同样用strncmp进行判定
		memset(C,0,sizeof(C));
	}

关于服务器端sqlite3_exec里面的回调函数CBcode如下:【服务器端】

int CBcode(void *args,int columnNum,char ** columValue,char **columnName)
{
    int * pid = (int *)args;   //强转以拿到与对应客户端沟通的socket文件描述符
	int socket = *pid;  //通信fd
	myfind MYfind;
	memset(&MYfind,0,sizeof(myfind));
	strcpy(MYfind.username,columValue[0]); //赋值数据库内第0列找到的数据a【找到才会进来,找不到这个函数就不会运行,也不会发送任何东西。为什么是第0列,因为我们创建的时候就把username放定义在了第0列】
	strcpy(MYfind.password,columValue[1]); //赋值数据库内找到的数据b
	printf("结构体搜寻账号为%s,密码为%s\n",MYfind.username,MYfind.password);
    send(socket,&MYfind,sizeof(myfind),0);
	return 0;
}

这里再展示一下客户端main.c流程 【客户端】

#include "../include/main.h"
int main(int argc, char *argv[])
{
	char buf[200]={0};  
	int sock = MYSOCKET(); //创建套接字文件
	connectserver(sock,argv[1],argv[2]);
	recv(sock,buf,sizeof(buf),0);  //接收服务器提示
	printf("%s\n",buf);
	int OP;
	while(1)
	{ 
		printf("|----------------------------------------------|\n");
		printf("|选项1-----------输入账号密码------------------|\n");
		printf("|选项2-----------注册账号密码------------------|\n");
		printf("|选项0--------------退出程序-------------------|\n");
		printf("|______________________________________________|\n");
		scanf("%d",&OP);	
		if(OP == 0)
		{return 0;}
		switch(OP)
		{
		case 1: 
			{
				send(sock,"coming #",10,0);  //基础命令,其他收发与服务器对应
				printf("请输入您的账号和密码,格式为【账号 密码#】\n"); 
				getchar();
				int S =  sendfile1(sock);//登陆账号密码的子函数
				if(S!=0)
				{
					printf("请重新输入账号密码!\n");
					return -1;
				}
				break;
			}
		case 2:  {
					 send(sock,"create #",10,0); 
					 printf("输入账号密码,格式【账号 密码#】\n");
					 sleep(1);
					 getchar();
					 char use[1000]={0}; char a[20]={0}; char b[20]={0}; 
					 fgets(use,sizeof(use),stdin);
					 parsecode(use,a,b);
					 printf("输出账号密码分别为%s %s\n",a,b);
					 send(sock,a,sizeof(a),0);
					 sleep(1);
					 send(sock,b,sizeof(b),0);
					 memset(use,0,sizeof(use));
					 recv(sock,use,sizeof(use),0);
					 printf("%s\n",use);
					 sleep(2);
					 printf("注册识别完成\n");
					 return 0; //注册
				 }
		} 
		char ceshi[50]={0};
		recv(sock,ceshi,sizeof(ceshi),0); //用来接收成功或单一变量生成时,发送的错误信息
        但不打印其信息,对应的是case1输入密码
		break;
}

里面的输入密码的sendfile1为:【客户端】

#include "../include/main.h"
//函数功能,发送账号密码至服务器进行对比
//参数一,套接字文件 
//返回值:成功0 失败-1
int sendfile1(int sock)
{
	char buf[40]={0};
	char usename[20]={0};
	char code[20]={0};
	fgets(buf,sizeof(buf),stdin);
	parsecode(buf,usename,code);//客户端内部解析用户名命令发送
	printf("输出账号密码分别为%s %s\n",usename,code);
	send(sock,usename,strlen(usename),0);  //信息1 输出的账号
	sleep(1);
	send(sock,code,strlen(code),0); 信息2:输出的密码
	sleep(1);
	myfind MYfind;  //声明接收结构体,结构体内容为从数据库拉出来的账号密码信息,没有对比到或者输入错误返回来的肯定是无法通过下面的操作
	memset(&MYfind,0,sizeof(myfind));
	int tc = recv(sock,&MYfind,sizeof(myfind),0);  //收账号信息
	if(tc<0) printf("接收失败\n");
	printf("用户名为%s,接收账号为%s\n",MYfind.username,MYfind.password);
 	
   if (strncmp(usename,MYfind.username,strlen(usename)!=0)) //对比服务器从数据库搜寻的内容和输出的内容
	{
		printf("用户名识别异常!\n");
		return -1;
	}
	printf("用户名识别成功!\n");

	if (strncmp(code,MYfind.password,strlen(code)!=0))
	{
		printf("密码识别异常!\n");
		return -1;
	}
	printf("密码识别成功!\n");
	return 0;
}

以上就是登录注册界面详细信息,其他的子函数只需要发送命令,对比命令,执行子函数再服务器,然后交互信息即可。最后给大家看一下详细执行结果

-----------------------------------------------------我是分割线-------------------------------------------------------------

二,展示界面

实现功能1 :多端查看

实现功能2:注册和密码登录

 三,乐器商城功能

流程:识别基础命令->识别二级命令->执行二级命令->两边互通->实现需求 

综合以上,即使本次乐器商城的思路与一些实际操作例子。

此次操作的库头文件如下:我就不一一解释了,建议大家查询系统手册。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sqlite3.h>
#include <sys/time.h>
#include <pthread.h>
#include <signal.h>

如有疑问、错误欢迎私聊纠正。祝大家敲的愉快!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux下的Tcp通信项目范例【demo】 的相关文章

  • 修改linux下的路径

    虽然我认为我已经接近 Linux 专业人士 但显然我仍然是一个初学者 当我登录服务器时 我需要使用最新版本的R 统计软件 R 安装在 2 个地方 当我运行以下命令时 which R I get usr bin R 进而 R version
  • bluetoothctl 到 hcitool 等效命令

    在 Linux 中 我曾经使用 hidd connect mmac 来连接 BT 设备 但自 Bluez5 以来 这种情况已经消失了 我可以使用 bluetoothctl 手动建立连接 但我需要从我的应用程序使用这些命令 并且使用 blue
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • awk 子串单个字符

    这是columns txt aaa bbb 3 ccc ddd 2 eee fff 1 3 3 g 3 hhh i jjj 3 kkk ll 3 mm nn oo 3 我可以找到第二列以 b 开头的行 awk if substr 2 1 1
  • Android:ANT 构建失败,并显示 google-play-services-lib:“解析为没有项目的 project.properties 文件的路径”

    我正在尝试使用 ANT 构建我的应用程序 但在包含 google play services lib 库项目后 我惨遭失败 Step 1 我在 project properties 文件中设置了对库项目的引用 android library
  • 如何通过替换为空页映射来取消映射 mmap 文件

    Linux 用户空间有没有办法用空页面 映射自 dev null 或者可能是一个空页面 重复映射到从文件映射的页面的顶部 对于上下文 我想找到这个 JDK bug 的修复 https bugs openjdk java net browse
  • 跟踪 Linux 程序中活跃使用的内存

    我想跟踪各种程序在特定状态下接触了多少内存 例如 假设我有一个图形程序 最小化时 它可能会使用更少的内存 因为它不会重新绘制窗口 这需要读取图像和字体并执行大量库函数 这些对象仍然可以在内存中访问 但实际上并没有被使用 类似的工具top它们
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • UWP 无法在两个应用程序之间创建本地主机连接

    我正在尝试在两个 UWP 应用程序之间设置 TCP 连接 当服务器和客户端在同一个应用程序中运行时 它可以正常工作 但是 当我将服务器部分移动到一个应用程序并将客户端部分移动到另一个应用程序时 ConnectAsync 会引发异常 服务器未
  • Erlang gen_tcp 连接问题

    简单的问题 这段代码 client gt SomeHostInNet localhost to make it runnable on one machine ok Sock gen tcp connect SomeHostInNet 56
  • chown:不允许操作

    我有问题 我需要通过 php 脚本为系统中的不同用户设置文件所有者权限 所以我通过以下命令执行此操作 其中 1002 是系统的用户 ID file put contents filename content system chown 100
  • 中断 Select 以添加另一个要在 Python 中监视的套接字

    我正在 Windows XP 应用程序中使用 TCP 实现点对点 IPC 我正在使用select and socketPython 2 6 6 中的模块 我有三个 TCP 线程 一个读取线程通常会阻塞select 一个通常等待事件的写入线程
  • 域套接字“sendto”遇到“errno 111,连接被拒绝”

    我正在使用域套接字从另一个进程获取值 就像 A 从 B 获取值一样 它可以运行几个月 但最近 A 向 B 发送消息时偶尔会失败 出现 errno 111 连接被拒绝 我检查了B域套接字绑定文件 它是存在的 我也在另一台机器上做了一些测试 效
  • 两种情况或 if 哪个更快? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我必须制作一个 非常 轻的脚本 它将接受用户的选项并调用脚本中的函数来执行一些任务 现在我可以使用 IF 和 CASE 选项 但我想知道两
  • 将 PDF 转换为 600dpi 的 TIFF 和 jpg 96 dpi

    我想使用 ImageMagick 从 Python 脚本将 pdf 转换为 600 dpi 的 tiff 和 96 dpi 的 jpg 我使用 imagemagick 命令行完成了这项任务 但我想使用python中的Imagemagick将
  • Linux:在文件保存时触发 Shell 命令

    我想在修改文件时自动触发 shell 命令 我认为这可以通过注册 inotify 挂钩并调用来在代码中完成system 但是是否有更高级别的 bash 命令可以完成此任务 尝试 inotify 工具 我在复制链接时遇到问题 抱歉 但 Git
  • 如何在apache 2.4.6上安装apxs模块

    我刚刚用过apt get update我的 apache 已更新为2 4 6 我想安装 apxs 来编译模块 但收到此错误 The following packages have unmet dependencies apache2 pre
  • 如何在shell中输出返回码?

    我正在尝试通过调用自定义 shell 脚本sh bin sh c myscript sh gt log txt 2 gt 1 echo 该命令的输出是创建的后台进程的 PID 我想指导 bin sh保存返回码myscript sh到某个文件
  • 在 Linux 上使用多处理时,TKinter 窗口不会出现

    我想生成另一个进程来异步显示错误消息 同时应用程序的其余部分继续 我正在使用multiprocessingPython 2 6 中的模块来创建进程 我试图用以下命令显示窗口TKinter 这段代码在Windows上运行良好 但在Linux上
  • jpegtran 优化而不更改文件名

    我需要优化一些图像 但不更改它们的名称 jpegtran copy none optimize image jpg gt image jpg 但是 这似乎创建了 0 的文件大小 当我对不同的文件名执行此操作时 大小仍然完全相同 怎么样 jp

随机推荐

  • Qt播放视频报错 DirectShowPlayerService::doRender: Unresolved error code 0x80040266

    没有插件报错 xff1a DirectShowPlayerService doRender Unresolved error code 0x80040266 如果文件路径不对或者文件名是中文的 xff0c 则会显示如下错误 xff1a Di
  • 树莓派使用(二)树莓派键盘布局,英式键盘换成没事键盘,解决#@无法输入问题

    树莓派键盘布局 xff0c 英式键盘换成没事键盘 xff0c 解决 64 无法输入问题 树莓派默认情况下 xff0c 输入 得到的是这个 符号 xff0c 输入 64 得到的是 34 这个符号 因为树莓派的系统默认是英文环境 xff0c 使
  • 阿里云Linux服务器安装可视化桌面,登录VNC提示Login incorrect*

    登录VNC提示Login incorrect 解决方法只要分为两步 xff1a 1 重置VNC密码 xff1a 先重置VNC密码 xff0c 重置后重启 xff0c 按照要求重置 xff0c 重置成功后会看到右上角出现一个重置成功的字样 2
  • 在计算机视觉论文中benchmark和baseline的区别

    总结 benchmark一般是和同行中比较牛的算法比较 xff0c 比牛算法还好 xff0c 那你可以考虑发好一点的会议 期刊 xff1b baseline一般是自己算法优化和调参过程中自己和自己比较 xff0c 目标是越来越好 xff0c
  • Gazebo仿真建模总结

    Gazebo仿真建模总结 目录 Gazebo仿真建模总结前言介绍总体框架框架介绍1 机器人模型urdf xacro2 模型运行平台rvizdisplayszh launch启动文件代码 xff1a 3 模型仿真平台gazebo1 xff09
  • c++工程中make和cmake的使用(CMakeLists.txt)

    一 make和cmake 1 make make xff0c 常指一条计算机指令 xff0c 可以从一个名为Makefile的文件中获得如何构建程序的依赖关系 通常项目的编译规则就定义在makrfile 里面 xff0c 比如 xff1a
  • 2. 阿里云上搭建ubuntu16.04并使用VNC进行远程连接

    首先 xff0c 用xshell连接阿里云 xff08 便于后续操作方便 xff09 参考文档 xff1a 阿里云服务器 xff08 Ubuntu16 04 64位 xff09 远程连接 再来创建新用户 参考文档 xff1a 为Ubuntu
  • 【哈工大李治军】操作系统课程笔记9:设备驱动与文件管理(显示器、键盘和磁盘)

    xff08 应粉丝催更 xff0c 笔记提前放出来了 xff0c 还剩最后一个视频 xff0c 等有空了再整理 xff09 1 I O与显示器 xff08 终端设备输出 xff09 本次所学的I O设备主要归为两大类 xff1a 键盘和显示
  • MathType7新版本数学公式编辑器上线功能特性

    许多论文或文献中含有大量较复杂的公式或者符号 xff0c 为了使文章中的公式符号更加规范 美观 xff0c 现在很多人选用MathType软件来编辑公式 MathType具有非常强大的公式编辑能力 xff0c 和我们常用的Office软件结
  • LDO:低压差线性稳压芯片

    LDO LDO即low dropout regulator xff0c 是一种 低压差 线性稳压器 这是相对于传统的线性稳压器来说的 传统的线性稳压器 xff0c 如78XX系列的芯片都要求输入电压要比输出电压至少高出2V 3V xff0c
  • git使用gitee 仓库教程详细

    1 先再本地创建 一个git 仓 先创建一个文件夹 在文件夹内运行git 执行git init 命令生成git 仓库 生成git 仓库之后 创建一个想要上传到云库的文件 xff0c 然后通过 git add 添加所有文件命令 添加跟踪 也叫
  • realsenseD435i运行vins-mono

    目录 写在前面准备编译vins mono 修改launch realsense vins mono 运行参考完 写在前面 1 本文内容 realsenseD435i运行vins mono 2 平台 ubuntu1804 ros melodi
  • Hive源码阅读--SQL的语法解析和语义分析--Driver

    前面五个类 xff0c 殊途同归都是CliDriver类 xff0c 他负责接受用户在命令行上输入的信息 xff0c 然后准备执行并将执行的结果返回 而真正底层干事情的是Driver xff0c 他将接受到的命令编译 xff0c 优化为MR
  • C语言字符串结束符“\0”

    C语言字符串结束符 0
  • STM32 PCB设计

    看了自己2018年2月画的PCB和现在2019年7月画的PCB xff0c 不多说了 不多说了 不多说了上图 96 2018年2月 96 2019年7月 大家可以明显看到第一块板子简直就是惨不忍睹 说几点PCB设计注意事项和自己的感想 xf
  • Java 调用第三方接口方法

    Java 调用第三方接口方法 一 通过JDK网络类Java net HttpURLConnection 1 java net包下的原生java api提供的http请求 使用步骤 xff1a 1 通过统一资源定位器 xff08 java n
  • docker基本命令及使用实例

    docker基本命令 特别鸣谢 xff1a B站up主 狂神说java的视频 xff0c 让我能短时间了解docker docker文件系统 docker镜像为分层设计 xff0c 相比于全量的虚拟机镜像 xff0c 少了引导程序bootf
  • ubantu 系统分区介绍

    假设分区有40个G 1 500M引导分区 2 10个G的swap分区 swap是一个内存交换空间 xff0c 当内存溢出 xff0c 或者计算机打算休眠的时候 会将数据存在swap分区中 在windows系统中是三个文件 swap的大小通常
  • H3C交换机常用命令(初学)

    一 显示交换机当前的一些配置信息 1 display current configuration 显示当前的一些配置信息 xff0c 如vlan xff0c 端口详细信息 2 display saved configuration 显示下次
  • Linux下的Tcp通信项目范例【demo】

    一 适合阅读对象 2 4个月的初学者 C语言编程方向 xff09 二 项目内容 xff1a 设计一个可以符合多用户进行线上查阅乐器的商城 xff0c 要求可以多个用户查看 xff0c 管理员可随时修改内容 xff0c 普通用户仅可查看 xf