linux 多线程客户端服务端通信,[转载]多线程实现服务器和客户端、客户端和客户端通信;需要代码,留言...

一、实验名称

动手打造自己的 IM

二、实验目的

1本次实验旨在锻炼大家的Socket编程能力,以日常生活中广泛使用的IM软件为背景,培养大家对于网络编程的兴趣。

2、通过本次实验,培养linux环境下网络编程能力,使得我们对网络应用层的网络应用软件有了一个深入的理解,这对网络课程的学习起到了很好的实践作用。

三、实验内容及步骤

实验内容:本作业要求同学们完成一个简陋的IM的客户端和服务器端,实现一些最基本和最常用的IM功能:

客户端功能:

1、4个以!开头命令,!login登录命令!list列出在线用户命令!file传输文件命令!logoff注销命令。

2、回显功能:当其他用户登录或者登出时,客户端会收到服务器的提示信息,当向另一个客户端发送文件之后,也会收到该客户端的提示信息。

3、聊天功能:两个客户端可以进行聊天:

以[username]: 开头的行为其他用户向你发送的聊天信息。

以>>[username]: 开头的行为你向其他用户发送的聊天信息。

服务器功能:

Server端基本架构:多进程并发服务器实现,为每个在线用户分配一个进程用以和在线用户保持通信,并在子进程退出(某用户下线)时,回收子进程资源。

ü服务器端固定端口:8081

ü用户登录成功,反馈提示信息

ü维护在线用户信息:包括IP地址和端口号,用户名字,用户密码等

ü向在线用户发出其他用户上/下线提示信息

实验步骤:

1、熟悉Linux下C语言的编程环境和编译方法,学会用gedit来编写并修改代码及命令行工具。

2、学习有关socket方面的有关知识,尝试着去编写服务器端和客户端的实现连接的代码,最重要的是学会使用socket()、listen()、bind()、connect()、accept()等函数的使用方法,在此基础上实现客户端和服务器端的连接。

3、在实现客户端和服务器端连接的基础上编写处理!login、!logoff、!list等简单的命令(无需客户端与客户端交互),这个过程最重要的是学会send()、recv()函数的使用,传递套接字时要注意接收和发送的对应。

4、在实现了单个客户端与服务器的用简单命令交互的基础上,学习线程的有关知识在服务器端创建多线程,实现服务器可以和多个客户端交互的功能。此过程最重要的是学会线程创建和使用,最重要的是pthread_create(4个参数)的使用,其中关键的地方是线程函数的建立及其参数的传递,参数是socket,这样才能在线程中实现与客户端的交互。

5、在实现了多个客户端与服务器进行交互的基础上,就有可能实现客户端与客户端的交互,编程时一个很关键的地方就是所使用的数据结构,没有一个存储logined客户端的数据结构,就很难实现客户端与客户端的交互。因此需要建立一个结构体来存储客户端的socket、port(可选)、username、flag(状态)。

两种方案:

1)从服务器获得另一个客户端的端口号和IP后,让客户端与客户端建立连接,实现直接交互,这就是P2P结构,编程时我试着使用了这种方法,但是连接总是出问题。

2)通过服务器实现客户端之间的交互,简单来说就是客户端把信息通过socket发送到服务器,服务器再把信息通过不同的socket发送到客户端,这是建立在每个客户端都有自己的socket的基础上的。

我选择了第二种方案来实现客户端的交互。

6、编程进行到这里,我突然意识到了如果客户端没有监听服务器的代码,无法接收和识别服务器的信息是客户端要发送的信息、还是服务其本身要发送的信息,思考良久,无奈之下只能大篇幅的修改代码,在客户端使用双线程,一个用于监听键盘的输入,一个用于监听服务器是否发送信息;这样当键盘输入时一个线程接收并负责向服务器发送信息,当收到服务器发送的信息时,另一个线程接收并把信息输出到终端上。

7、在以上的基础上,就可以实现客户端的通话及文件的发送,最后就是调试程序并整理输出的格式。

四、实验分析

1,server.c编译及运行结果:

a4c26d1e5885305701be709a3d33442f.png

图1处于监听状态的服务器

2,开启另外终端运行客户端程序:

第一个用户:Me,运行客户端程序之后,使用命令!login登录,成功登录后会收到服务器的发送的信息,结果如下:

a4c26d1e5885305701be709a3d33442f.png

图2 一个client登陆成功后的服务器

a4c26d1e5885305701be709a3d33442f.png

图3第一个客户端Me登陆成功

另起两个终端第二个客户端You和第三个客户端Him登录后结果如下:

a4c26d1e5885305701be709a3d33442f.png

图4多个客户端登陆后的服务器

3,指令!list的使用:

a4c26d1e5885305701be709a3d33442f.png

图5 Me客户端上执行!list命令

4,!logoff命令:当用户Me执行!logoff后,客户端显示服务器发送的信息,此时使用!list指令,结果如下:

a4c26d1e5885305701be709a3d33442f.png

图6客户端Him执行!logoff命令

a4c26d1e5885305701be709a3d33442f.png

图7客户端Him执行!logoff命令后Me执行!list的结果

5,聊天功能演示:

a4c26d1e5885305701be709a3d33442f.png

图8 Me客户端和You客户端进行通话

a4c26d1e5885305701be709a3d33442f.png

图9You客户端和Me客户端通话

6,指令!file的使用,文件传输功能演示:

a4c26d1e5885305701be709a3d33442f.png

图10You客户端向Me发送lilufeng.pdf文件显示成功

a4c26d1e5885305701be709a3d33442f.png

图11 Me客户端接收文件成功信息

7、几种错误处理,结果如下:

a4c26d1e5885305701be709a3d33442f.png

图12用户名错误登录失败

a4c26d1e5885305701be709a3d33442f.png

图13发送文件时用户不在线、发送失败

a4c26d1e5885305701be709a3d33442f.png

图14Me想和You对话,You没有登录,连接失败

五、实验结论

难点:

1、本实验是基于Linux环境下,使用C语言编写而成,这两者都需要实验前进行深入的探索和学习,对我而言,加大了编程和实现的难度。

2、对socket和thread方面的知识可以说一无所知,编程的过程中要不断地学习才能向前迈一小步。

感受:

1、这次实验的过程中,我深知自己的知识的匮乏,实验的过程可以说完全是一个探索的过程,对用到的函数我必须要在Dev等工具下先进性一定的应用和学习才能真正掌握其用法和内涵,实践的过程中学到了很多的知识,而且在编程的后面阶段感觉对这些知识已经能够熟练地应用,最有说服力的就是那些函数的掌握,可见,软件这个行业只有在实践中才能真正的学到本领。

2、编程的前后,我的代码被改了很多遍,因为开始编程的时候没有一个整体的构思,只能走一步算一步,每走一步都是那么的艰难,线程的加入和数据结构的改变都使原来的代码结构发生天翻地覆的变化,到最后在客户端加入双线程时整体的代码又改了一遍,所以说这次试验让我感觉非常的累,而且过程中感觉网络编程是那么的复杂,现在想想这些东西,还是很简单的。由此,我明白了开发软件前为什么要进行详细的设计,看着是浪费时间,其实那是在节省时间和精力,而且是开发出一个软件的基础。

3、通过这次试验让我学会了关于网络的socket和P2P等很多知识,这些知识在短期或者说今生难于忘记,当然还有操作系统方面的thread和process方面的知识。

4、同时我也感受到了IT人士的辛劳,其实我一直都在感受到,只不过这次更加强烈罢了,不过辛劳后,看到自己的成果和感到内心的充实,觉得付出还是值得的。

客户端程序源码:

//[浠g爜]

tcpclient.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define

SERVER_PORT 8081  //

define the defualt connect port

id

#define

BUFFER_SIZE 255 //buf size

int

clifd,length = 0;//socket size

char

buf[BUFFER_SIZE]; //the buffer of socket

pthread_t

thread;//thread discription

char

command[100],uName[20],pwd[20];

void

*listenServer(int);//listen and receive message from the server

int

cli_socket_connect_server(int);//create socket and connect the

server

int

main(int argc)

{

clifd =

cli_socket_connect_server(SERVER_PORT);//return the socket

while(1)

{ char

frontcmd[20],ch1,ch2;

int countcmd

=0,countFcmd=0;

memset(frontcmd,' ',sizeof(frontcmd));

memset(command,' ',sizeof(command));

memset(buf,' ',sizeof(buf));

while(ch1 =

getchar()) //input the command

{

if(ch1 == ' ')

{

while(ch2 =

getchar())

{

if(ch2 == 'n')

break;

else

command[countcmd++]

= ch2;

}

break;

}

else if(ch1 ==

'n')

break;

else

frontcmd[countFcmd++] = ch1;

}//input

over:frontcmd is the really command

if(frontcmd[0] ==

'>')//talk function process

{

strcpy(buf,">>");

send(clifd,buf,BUFFER_SIZE,0);

char *talkto;

talkto =

strtok(frontcmd,">:");

strcpy(buf,talkto);//talk to whom

strcat(buf,":");//:

is used to strtok in the server

strcat(buf,command);//what you send

send(clifd,buf,BUFFER_SIZE,0);

}

if(strcmp(frontcmd,"!logoff") == 0)//logoff command process

{

strcpy(buf,"!logoff");

send(clifd,buf,BUFFER_SIZE, 0);

strcpy(buf,uName);

send(clifd,buf,BUFFER_SIZE, 0 );

close(clifd);

pthread_exit(NULL);

break;

}//end of logoff

if

if(strcmp(frontcmd,"!list") == 0)//list command process

{

strcpy(buf,"!list");

send(clifd,buf,BUFFER_SIZE, 0 );

}//end of list

if

if(strcmp(frontcmd,"!login") == 0)//login command process

{

strcpy(buf,"!login");

send(clifd,buf,BUFFER_SIZE, 0 );

printf("User

name:t");

scanf("%s",uName);

printf("Password:t");

scanf("%s",pwd);

strcpy(buf,uName);

send(clifd,buf,BUFFER_SIZE, 0 );

length =

recv(clifd,buf,BUFFER_SIZE,0);

if

(length < 0)

{

printf(" error comes

when recieve data from server! send filen");

exit( 1 );

}

printf("From

server:nt%sn",buf);

if(pthread_create(&thread, NULL, (void

*)listenServer, (void *)clifd) == 0) //after login success create

the listenServer thread

{

printf("listen

thread create success!n");

}

else

{

printf("listen

thread create failed!n");

exit(1);

}

}//end of login

if

if(strcmp(frontcmd,"!file") == 0)

{

strcpy(buf,frontcmd);//send front command(!file) to the server

send(clifd,buf,BUFFER_SIZE,0);

char

*file,*toUser;

file =

strtok(command," =>");//file

toUser =

strtok(NULL," =>");//destination user

printf("filename:t%sntoUser:t%s",file,toUser);

strcpy(buf,toUser);//send the file to whom

send(clifd,buf,BUFFER_SIZE,0);

}//end of file

if

}//end of while

return 0;

}

void

*listenServer(int file_socket)

{

while(recv(file_socket,buf,BUFFER_SIZE,0)>0)

{

char *flagcmd =

NULL,*printInfo = NULL;

flagcmd =

strtok(buf,"|");

printInfo =

strtok(NULL,"|");

if(strcmp(flagcmd,"!list") == 0)//list the user that logined

now

printf("from

server:n%s",printInfo);

else

if(strcmp(flagcmd,"!logoff") == 0)//logoff

printf("from

server:nt%s",printInfo);

else

if(strcmp(flagcmd,"!file") == 0)//send the file

{

if(strcmp(printInfo,"0") == 0)//destination user does not login

printf("From

server:ntuser does not login,file failed!n");

else

//destination user logined

printf("nConnect

success!file success!n");

}

else

if(strcmp(flagcmd,"!msg") == 0)//receive the file message

{

printf("From

sever:nt%s",printInfo);

}

else

if(strcmp(flagcmd,"!talk") == 0)//talk message

{

if(strcmp(printInfo,"0") == 0)

printf("The user

does not login!n");

else

printf("%sn",printInfo);

}

else

printf("Please

debug!");

}

}

int

cli_socket_connect_server(int serverPort)

{

struct

sockaddr_in cliaddr;

socklen_t socklen

=  sizeof(cliaddr);

char

sever[20];//store the IP

int

client_socket;

if((client_socket

=  socket(AF_INET,SOCK_STREAM, 0

))  <  0

)//create socket of the client

{

printf(" create

socket error!n ");

exit( 1 );

}

bzero(

& cliaddr,sizeof(cliaddr));

cliaddr.sin_family

=  AF_INET;

inet_aton(sever,

& cliaddr.sin_addr);

cliaddr.sin_port

=  htons(serverPort);//port of

the sever

cliaddr.sin_addr.s_addr  =

htons(INADDR_ANY);//the same IP with the

sever.Connect auto!

if(connect(client_socket,(struct  sockaddr * )

& cliaddr, socklen)

<  0 )//connect

the server

{

printf(" can't

connect!n ");

exit( 1 );

}

return

client_socket; //return the socket

}

服务器端源码:

//tcpserver.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define

SERVER_PORT 8081  //

define the defualt connect port

id

#define

LENGTH_OF_LISTEN_QUEUE 10  //

length of listen queue in server

#define

MAX_THREAD 10

#define

BUFFER_SIZE 255

#define

SUCCESS_MESSAGE "Login

Success!"

#define

FAIL_MESSAGE "Login Failed!"

#define

TOTAL_USER_NUM 6

struct

clientInformation

{

int flag;

//record

the struct state: 0 is empty

char loginUsr[20];

//the users that have logined

int socket;

//store the logined uses'

socket

};

struct

clientInformation clientInfo[TOTAL_USER_NUM];//logined users'

array

int

servfd,sever_socket;  //the socket

int len=0;

//record the length of the socket

int numOfThread = 0;

//record the number of

threads

char users[6][10] =

{"Me","You","Him","Her","user","tmd"};//users that can login

char

buf[BUFFER_SIZE];  //the capacity of the

socket

pthread_t

thread[MAX_THREAD]; //thread discription

struct

sockaddr_in servaddr,cliaddr;

void*

docommand(int);//thread function

int main(int

argc)

{

int num;

for(num = 0; num

< TOTAL_USER_NUM; num++)

{

clientInfo[num].flag

= 0;

clientInfo[num].socket = 0;

}

if  ((servfd  =

socket(AF_INET,SOCK_STREAM, 0 ))

<  0 )//create

socket in the server

{

printf(" create socket

error!n ");

exit( 1

);

}

bzero( &

servaddr,sizeof(servaddr));

servaddr.sin_family  =

AF_INET;

servaddr.sin_port  =

htons(SERVER_PORT);

servaddr.sin_addr.s_addr  =

htons(INADDR_ANY);

if(bind(servfd,(struct  sockaddr

* ) & servaddr,sizeof(servaddr)) < 0

)//bind

{

printf(" bind to

port %d failure!n ",SERVER_PORT);

exit( 1

);

}

if(listen(servfd,LENGTH_OF_LISTEN_QUEUE)

<  0

)//listen

{

printf("

call listen failure!n ");

exit( 1

);

}

while(numOfThread

< MAX_THREAD)

{

socklen_t length

=  sizeof(cliaddr);

sever_socket  =

accept(servfd,(struct  sockaddr

* ) & cliaddr, & length);//accept

the login

if

(sever_socket  <

0 )

{

printf("

error comes when call accept!n ");

break;

}

else

{

//void* arg[] =

{&sever_socket};

if(pthread_create(&thread[numOfThread++], NULL,

(void *)docommand, (void *)sever_socket) != 0)

printf("绾跨▼%d鍒涘缓澶辫触!n",numOfThread); //create

the new thread to the login client

else

printf("绾跨▼%d琚垱寤簄",numOfThread);

}

}

close(servfd);

return  0

;

}

void *docommand(int

sever_socket)

{

while

( 1 )

{// server loop will nerver exit unless any body kill the process

memset(buf,' ',sizeof(buf));

len

=  recv(sever_socket, buf,

BUFFER_SIZE, 0);  //recv the

command

if

(len < 0)

{

printf(" error comes when

recieve data from client ! " );

exit( 1 );

}

else

{

if(strcmp(buf,">>") == 0) //talk

process

{

len

=  recv(sever_socket, buf,

BUFFER_SIZE, 0);//recv the user name that the file will be sent

to

if

(len < 0)

{

printf("error comes when

recieve data from client ! " );

exit( 1 );

}

char

temp[100],*talkto;

strcpy(temp,buf);//temp store what will be sent

talkto =

strtok(buf,":");

int j;

for(j = 0;j

< TOTAL_USER_NUM;j++)

{

if(clientInfo[j].flag == 1)

{

if(strcmp(clientInfo[j].loginUsr,talkto) == 0)

{

strcpy(buf,"!talk|");

strcat(buf,temp);//move temp(the information) to buf

send(clientInfo[j].socket,buf,BUFFER_SIZE,0);//send the talking

message to whom what you talk

break;

}

}

}

if(j ==

TOTAL_USER_NUM)

{

strcpy(buf,"!talk");

strcat(buf,"|0");//"0" == user does not login

send(sever_socket,buf,BUFFER_SIZE, 0 ); //send message(user does

not login)

}

}

else

if(strcmp(buf,"!file") == 0)  //file process

{

len

=  recv(sever_socket, buf,

BUFFER_SIZE, 0);//recv the user name that the file will be sent

to

if

(len < 0)

{

printf("error comes when

recieve data from client ! " );

exit( 1 );

}

int i;

for(i = 0;i

< TOTAL_USER_NUM;i++)

{

if(clientInfo[i].flag == 1)

{

if(strcmp(clientInfo[i].loginUsr,buf) == 0)

{

strcpy(buf,"!file|");

strcat(buf,"1");//"1" == user logined

send(sever_socket,buf,BUFFER_SIZE, 0 ); //send to the client who

send file(receiver)

strcpy(buf,"!msg|nreceived the file!n");

send(clientInfo[i].socket,buf,BUFFER_SIZE,0);//tell the client to

recv the file

break;

}

}

}

if(i ==

TOTAL_USER_NUM)

{

strcpy(buf,"!file");

strcat(buf,"|0");//"0" == user does not login

send(sever_socket,buf,BUFFER_SIZE, 0 ); //send message(user does

not login)

}

}//end of if

else

if(strcmp(buf,"!list") == 0)  //list the logined users process

{

strcat(buf,"|");

int k;

for(k = 0; k

< TOTAL_USER_NUM; k++)

{

if(clientInfo[k].flag == 1)

{

strcat(buf,clientInfo[k].loginUsr);

strcat(buf,"n");

}

}

send(sever_socket,buf,BUFFER_SIZE,0); //send all logined users to

client

}//end of else if

1

else

if(strcmp(buf,"!logoff") == 0)  // logoff process

{

while(1)

{

strcat(buf,"|logoff

success!n");

send(sever_socket,buf,BUFFER_SIZE,0); //send logoff success

message

memset(buf,' ',sizeof(buf));

len

=  recv(sever_socket, buf,

BUFFER_SIZE, 0);  //recv the login users name

int k;

for(k = 0; k

< TOTAL_USER_NUM; k++)//move it out from the

clientinformation struct

{

if(strcmp(buf,clientInfo[k].loginUsr) == 0)

{

strcpy(clientInfo[k].loginUsr," ");

clientInfo[k].flag =

0;

clientInfo[k].socket

= 0;

break;

}

}

close(sever_socket);

numOfThread--;

pthread_exit(NULL);

break;

}

}//end of else if

2

else

if(strcmp(buf,"!login") == 0)//login process

{

len

=  recv(sever_socket, buf,

BUFFER_SIZE, 0); //recv the login user's name

if

(len < 0)

{

printf("error comes when

recieve data from client ! login" );

exit( 1 );

}

printf("from

client:%stIP:%stPort:%dn ",buf,

inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));

int i;

for(i = 0;i

< TOTAL_USER_NUM;i++)//judge whether have this

user

{

if(strcmp(buf,users[i]) == 0)

{

for(i = 0;i

< TOTAL_USER_NUM;i++)

{

if(clientInfo[i].flag == 0)

{

strcpy(clientInfo[i].loginUsr,buf);

clientInfo[i].socket

= sever_socket;

clientInfo[i].flag =

1;

break;

}

}

strcpy(buf,SUCCESS_MESSAGE);

send(sever_socket,buf,BUFFER_SIZE, 0 ); //send login success

message

break;

}

}

if(i ==

TOTAL_USER_NUM)

{

printf("No user

called %s! Login failed!n",buf);

memset(buf,' ',sizeof(buf));

strcpy(buf,FAIL_MESSAGE);

send(sever_socket,buf,BUFFER_SIZE, 0 ); //send login failed

message

}

}//end of else if

3

} //end of else

}// end of while

}

又不懂得地方,欢迎留言询问,我必尽力解答!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/503541.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 设置ssh并发度,在linux如何使用ControlPersist加快SSH连接速度的问题

不经意间我们又来到了文章的学习&#xff0c;在众多学习中&#xff0c;我们的文章也许不起眼&#xff0c;但是想必大家都有很多问题吧&#xff0c;所以重要的下面我们就来讲解一下&#xff0c;大家一定要认真看奥&#xff01;&#xff01;Linux系统进行服务器配置管理迁移的时候…

linux下c标准库位置,C 标准库 IO 使用详解

其实输入与输出对于不管什么系统的设计都是异常重要的&#xff0c;比如设计 C 接口函数&#xff0c;首先要设计好输入参数、输出参数和返回值&#xff0c;接下来才能开始设计具体的实现过程。C 语言标准库提供的接口功能很有限&#xff0c;不像 Python 库。不过想把它用好也不容…

linux docker查看容器状态,Docker容器状态命令行工具——Ctop

Ctop是和Linux top展示效果类似的一个容器状态监视工具&#xff0c;Ctop可以动态的显示容器的cpu、内存、网络的使用情况。一共有两个叫Ctop的命令行工具&#xff0c;分别由GO和Python实现。Python实现的版本功能更强大一些。GO实现版本安装Linux$ wget https://github.com/bci…

plsql表设置主键_对复制实施主键约束

作者&#xff1a;Pedro Gomes 译&#xff1a;徐轶韬在本文中&#xff0c;我们介绍一个配置选项&#xff0c;该选项控制复制通道是否允许创建没有主键的表。这延续了我们最近在复制安全性方面的工作&#xff0c;在该工作中&#xff0c;我们允许用户强制执行权限检查和/或强制执行…

一键刷入twrp_小米/红米手机到手了该怎么解锁和刷 twrp

资源准备&#xff1a;1.百度搜索小米解锁申请&#xff0c;进行申请解锁并下载解锁工具。如图。文件夹里有对应的驱动&#xff0c;要安装好。2.对应机型的 twrp。在 w大的微博下找(wzsx150)或者在酷安找或者去twrp官网。3.edxp相关的包(两个)(不需要框架的可以忽略)4.手(第一步&…

如何将计算思维融合到C语言程序设计中,浅析基于计算思维的C语言程序设计教学...

浅析基于计算思维的C语言程序设计教学摘要&#xff1a;C语言是关键词&#xff1a;计算思维;C语言;教学改革中图分类号&#xff1a;TP3 文献标识码&#xff1a;A文章编号&#xff1a;1009-3044(2020)16-0145-02C语言是计算机相关专业的必修基础课程&#xff0c;是学生接触的第一…

一直在构建工作空间_智能工作空间让Dropbox拥有无限扩展潜力

智能工作空间让Dropbox拥有无限扩展潜力Dropbox一直以“让工作变得更好”的使命。在竞争激烈的市场中&#xff0c;Dropbox有着卓越的历史&#xff0c;就连苹果创始人史蒂夫乔布斯曾经提出来要收购它。Dropbox的智能工作空间是一个开放的生态系统&#xff0c;由于其开放集成的特…

黄金分割小数点后100位小数的c语言编程,黄金分割数小数点后100位

满意答案su304_3212013.03.25采纳率&#xff1a;57% 等级&#xff1a;12已帮助&#xff1a;10017人黄金分割奇妙之处&#xff0c;在于其比例与其倒数是一样的。例如&#xff1a;1.618的倒数是0.618&#xff0c;而1.618:1与1:0.618是一样的。确切值为根号51/2黄金分割数是无理…

去超市一定要存包吗_去东京一定要去的富士河口湖

第一次去河口湖是一个人&#xff5e;也没有留宿&#xff0c;但当时就想说一定要来这边住两天泡温泉&#xff0c;因为实在太&#xff01;美&#xff01;了&#xff01;因为下面这个预告所以就订了一栋小木屋&#xff0c;这是闺蜜先去日本前线发回的&#xff5e;立马改了酒店日期…

分析启动耗时 android,Android app启动耗时分析

首先编译你的程序&#xff0c;打开Android Studio里面的Android Monitor&#xff0c;找到下图的按钮&amp;amp;amp;amp;amp;amp;lt;img src"//bbsmax.ikafan.com/static/L3Byb3h5L2h0dHBzL3BpYzIuemhpbWcuY29tL3YyLTA4Zjk1ZmUxMjM5ODgwNTkzMDU5YjE3YzFlMGU5NjcxX2IucG5…

android+内存清理+代码,最新版本:Android一键式清理,内存清理功能的实现

Android一键式清理&#xff0c;内存清理功能的实山清理大师等均提供一键式清理和一键加速等功能。实际上&#xff0c;它们杀死了一些后台进程以达到释放内存的目的。基本思想是列出所有正在运行的进程&#xff0c;检查它们的重要值(RunningAppProcessInfo.importance&#xff0…

cups共享linux打印机_linux入门-映射网络驱动器

linux入门-映射网络驱动器在日常中&#xff0c;我们不会时时刻刻远程着linux服务器&#xff0c;那么有没有办法可以让我们在window电脑上映射linux的磁盘呢&#xff1f;这是可以实现的&#xff0c;这里我们就要介绍samba了。sambaSamba是在Linux和UNIX系统上实现SMB协议的一个免…

html如何将设置文本效果,css如何对文本进行修饰

color属性&#xff1a;设置文本文字颜色。用法如下&#xff1a;color&#xff1a;颜色值;color属性可以设置的合法颜色值包括&#xff1a;16进制颜色值(例&#xff1a;#ffffff)&#xff0c;rgb颜色值【例&#xff1a;rgb(0,0,0)】&#xff0c;rgba颜色值【例&#xff1a;rgb(0,…

HTML与cgi post传递与接收,CGI实例--表单GET与POST示例

CGI概述CGI(Common Gateway Interface: 公用网关接口)规定了Web服务器调用其他可执行程序(CGI程 序)的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互, 也就是CGI程序通过读标准输入&#xff0c;接受Web浏览器发送给Web服务器的信息, 进行处理, 将响应结果再通过…

html鼠标滑轮换图片,JavaScript实现鼠标滚轮控制页面图片切换

鼠标上的滚轮是一个不错的东东&#xff0c;为什么这么说&#xff0c;因为它能帮助我们快速的浏览网页,快速的进行长篇文章的阅读。对于web前端的我们来说又怎么能不注重这个鼠标滚轮呢&#xff0c;那么它能如何让用户更好的浏览网页呢&#xff1f;本文主要介绍JavaScript实现鼠…

电脑视频html5全屏掉帧,Windows 10使用自带的电影和电视全屏看视频时掉帧(画面卡顿)...

Windows 10自带的“电影和电视”应用能应付一些常见的视频格式&#xff0c;还能播放360度全景视频&#xff0c;对部分人来说用它就够了&#xff0c;不需要额外安装其它播放视频的应用。在使用电影和电视全屏播放视频的过程中&#xff0c;部分人可能会出现掉帧情况&#xff0c;画…

微型计算机的alu部件是包含在,微型计算机的ALU部件是什么?

计算机中执行各种算术和逻辑运算操作的部件。运算器的基本操作包括加、减、乘、除四则运算&#xff0c;与、或、非、异或等逻辑操作&#xff0c;以及移位、比较和传送等操作&#xff0c;亦称算术逻辑部件(ALU)。计算机运行时&#xff0c;运算器的操作和操作种类由控制器决定。运…

工具系列:TensorFlow决策森林_(5)使用文本和神经网络特征

文章目录 设置使用原始文本作为特征使用预训练的文本嵌入同时训练决策树和神经网络构建模型训练和评估模型 欢迎来到 TensorFlow决策森林&#xff08; TF-DF&#xff09;的 中级教程。 在本文中&#xff0c;您将学习有关 TF-DF的一些更高级的功能&#xff0c;包括如何处理自…

超级计算机游戏电脑,Salad邀请PC玩家参与全球最大分布式超级计算机的构建

(来自&#xff1a;Salad 官网)据悉&#xff0c;自 2018 年成立以来&#xff0c;Salad 已经在 25 万名 PC 玩家的帮助下&#xff0c;利用闲置的硬件算力、以及开源的桌面应用程序&#xff0c;来帮助验证区块链交易。作为奖励&#xff0c;Salad 用户能够分享计算资源&#xff0c;…

更换锁定计算机图片,电脑锁屏图片怎么设置

电脑锁屏图片怎么设置觉得电脑锁屏的图片单调没有新意&#xff1f;其实大家想知道电脑锁屏图片应该怎么设置吗&#xff1f;下面是小编推荐给大家的电脑锁屏图片怎么设置&#xff0c;希望大家有所收获。同时按下窗口键winR&#xff0c;调出运行对话框&#xff0c;如下图所示运行…