Linux 系统应用编程——网络编程(服务器模型)

在网络通信过程中,服务端通常需要处理多个客户端。由于多个客户端的请求可能会同时到来,服务器端可采用不同的方法来处理。总体上来说,服务器端可采用两种模型来实现:循环服务器模型和并发服务器模型

        循环服务器模型是指服务器端依次处理每个客户端,直到当前客户端的所有请求处理完毕,再处理下一个客户端。这类模型的优点是简单,缺点显而易见。特别是TCP循环服务器模型,由于必须先处理完当前客户端,容易造成其他客户端等待时间较长的情况。

        为了提高服务器的并发处理能力,又引入了并发服务器模型。其基本思想是在服务器端此阿勇多任务机制(多进程或多线程),分别为每个客户端创建一个任务来处理,极大地提高了服务器的并发处理能力。

        下面具体介绍循环服务器模型和并发服务器模型的流程及实现。为了更好的进行对比。本节均以TCP为例讨论相关模型。

 

一、循环服务器(TCP)

1、运行介绍

       TCP循环服务器是一种常用的模型,其工作流程如下:

1)服务器端从连接请求队列中提取请求,建立连接并返回新的已连接套接字;

2)服务器端通过已连接套接字循环接收数据,处理并发送给客户端,知道客户端关闭连接;

3)服务器端关闭已连接套接字,返回步骤1;

 

2、特点分析

       通过上面对服务器执行过程的介绍,可以得到以下结论。

1)服务器端采用循环嵌套来实现。外层循环依次提取每个客户端的连接请求,建立TCP连接。内层循环接受并处理当前客户端的所有数据,知道客户端关闭连接;

2)如果当前客户端没有处理结束,其他客户端必须一直等待。

注意:采用这种模型的服务器无法同时为多个客户端服务。

 

3、编程示例

下面实现 TCP ECHO 服务器端和客户端。服务器端接收到客户端数据后,原封不动发送回去(回射服务);客户端运行时,用户从键盘输入字符串,发送给服务器端并接受返回的数据,直到用户输入quit 后退出。

server.c

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <sys/types.h>  
  5. #include <sys/socket.h>  
  6. #include <unistd.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #define BUFFER_SIZE 128  
  10. #define PORT 8888  
  11.   
  12. int main()  
  13. {  
  14.     int listenfd, clientfd;  
  15.     int n;  
  16.     struct sockaddr_in serveraddr,clientaddr;  
  17.     socklen_t peerlen;  
  18.     char buffer[BUFFER_SIZE];  
  19.   
  20.     if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)  
  21.     {  
  22.         perror("socket error");  
  23.         exit(-1);  
  24.     }  
  25.     else  
  26.     {  
  27.         printf("listenfd:%d\n",listenfd);  
  28.     }  
  29.   
  30.     memset(&serveraddr,0,sizeof(serveraddr));  
  31.     serveraddr.sin_family = AF_INET;  
  32.     serveraddr.sin_port = htons(PORT);  
  33.     serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  34.   
  35.     if(bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0) //绑定IP地址和端口号  
  36.     {  
  37.         perror("bind error");  
  38.         exit(-1);  
  39.     }  
  40.     else  
  41.     {  
  42.         printf("bind successfully!\n");  
  43.     }  
  44.   
  45.     if(listen(listenfd,10) == -1)  
  46.     {  
  47.         perror("listen error");  
  48.         exit(-1);  
  49.     }  
  50.     else  
  51.     {  
  52.         printf("listening....\n");  
  53.     }  
  54.   
  55.     peerlen = sizeof(clientaddr);  
  56.     while(1)  
  57.     {  
  58.         if((clientfd = accept(listenfd,(struct sockaddr *)&clientaddr,&peerlen)) < 0) //循环等待客户端的连接  
  59.         {  
  60.             perror("accept error");  
  61.             exit(-1);  
  62.         }  
  63.         else  
  64.         {  
  65.             printf("connection from [%s:%d]\n",inet_ntoa(clientaddr.sin_addr)  
  66.                     ,ntohs(clientaddr.sin_port));     
  67.         }  
  68.   
  69.         memset(buffer,0,sizeof(buffer));  
  70.         while(1)  
  71.         {  
  72.             if((n = recv(clientfd,buffer,BUFFER_SIZE,0)) == -1) //循环接收客户端发送的数据  
  73.             {  
  74.                 perror("recv error");  
  75.                 exit(-1);  
  76.             }  
  77.             else if(n == 0) //此时,客户端断开连接  
  78.             {  
  79.                 break;  
  80.             }  
  81.             else  
  82.             {  
  83.                 printf("Received message:%s\n",buffer);  
  84.                 if(send(clientfd, buffer, n, 0) == -1)  
  85.                 {  
  86.                     perror("send error");  
  87.                     exit(-1);  
  88.                 }  
  89.                 else  
  90.                 {  
  91.                     printf("sendmessage:%s\n",buffer);  
  92.                 }  
  93.             }  
  94.         }  
  95.         close(clientfd); //客户端断开连接后,服务端也断开  
  96.     }  
  97.     close(listenfd);  
  98.   
  99.     return 0;  
  100. }  

client.c

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <unistd.h>  
  5. #include <sys/socket.h>  
  6. #include <sys/types.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #define BUFFER_SIZE 128  
  10. #define PORT 8888  
  11.   
  12. int main()  
  13. {  
  14.     int n;  
  15.     int serverfd, clientfd;  
  16.     struct sockaddr_in serveraddr;  
  17.     char buffer[BUFFER_SIZE];  
  18.   
  19.     if((clientfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)  
  20.     {  
  21.         perror("socket error");  
  22.         exit(-1);  
  23.     }  
  24.     else  
  25.     {  
  26.         printf("clientfd:%d\n",clientfd);  
  27.     }  
  28. //设置服务端的IP地址和端口号  
  29.     memset(&serveraddr,0,sizeof(serveraddr));  
  30.     serveraddr.sin_family = AF_INET;  
  31.     serveraddr.sin_port = htons(PORT);  
  32.     serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  33.   
  34.     if(connect(clientfd,(struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)  
  35.     {  
  36.         perror("connect error");  
  37.         exit(-1);  
  38.     }  
  39.     else  
  40.     {  
  41.         printf("connect successfully!\n");  
  42.     }  
  43.   
  44.     while(1)  
  45.     {         
  46.         printf("input > ");  
  47.         fgets(buffer,sizeof(buffer),stdin);  
  48.         if(strcmp(buffer,"quit\n") == 0) //遇到quit,退出  
  49.             break;  
  50.         buffer[strlen(buffer) - 1] = '\0'//将'\n'去掉  
  51.         if(send(clientfd,buffer,sizeof(buffer),0) == -1)  
  52.         {  
  53.             perror("send error");  
  54.             exit(-1);  
  55.         }  
  56.         memset(buffer,0,sizeof(buffer)); //清空buffer  
  57.         if((n = recv(clientfd,buffer,sizeof(buffer),0)) == -1)  
  58.         {  
  59.             perror("recv error");  
  60.             exit(-1);  
  61.         }  
  62.         else if(n == 0)  
  63.         {  
  64.             break//若服务端意外关闭  
  65.         }  
  66.         else  
  67.         {  
  68.             printf("echo:%s\n",buffer);  
  69.         }  
  70.     }  
  71.     close(clientfd);  
  72.   
  73.     return 0;  
  74. }  

运行结果如下:

server

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/netprogram/2$ ./server   
  2. listenfd:3  
  3. bind successfully!  
  4. listening....  
  5. connection from [127.0.0.1:57366]  
  6. Received message:xiao  
  7. sendmessage:xiao  
  8. Received message:zhi  
  9. sendmessage:zhi  
  10. Received message:qiang  
  11. sendmessage:qiang  
  12.   
  13. //继续等待下一个客户端的连接  

client

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/netprogram/2$ ./client   
  2. clientfd:3  
  3. connect successfully!  
  4. input > xiao  
  5. echo:xiao  
  6. input > zhi  
  7. echo:zhi  
  8. input > qiang  
  9. echo:qiang  
  10. input > quit  
  11. fs@ubuntu:~/qiang/netprogram/2$   

 

二、并发服务器(TCP)

1、运行介绍

       TCP并发服务器模型在网络通信中被广泛使用,既可以采用多进程也可以采用多线程来实现。以多进程为例,其工作流程如下:

1)服务器端父进程从连接请求队列中提取请求,建立连接并返回新的已连接套接字。

2)服务器端父进程创建子进程为客户端服务。客户端关闭连接时,子进程结束。

3)服务器端父进程关闭已连接套接字,返回步骤1;

 

2、特点分析

通过上面对服务器执行过程的介绍,可以得到以下结论。

1)服务器端父进程一旦接受到客户端的连接请求,建立好连接并创建新的子进程。这意味着每个客户端在服务器端有一个专门的子进程为其服务。

2)服务器端的多个子进程同时运行(宏观上),处理多个客户端。

3)服务器端的父进程不具体处理每个客户端的数据请求。

注意:采用这种模型的服务器端需要避免僵死进程。

 

3、编程示例

下面采用并发模型实现 TCP ECHO服务器端。

server.c

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <sys/types.h>  
  5. #include <sys/socket.h>  
  6. #include <unistd.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #include <signal.h>  
  10. #define BUFFER_SIZE 128  
  11. #define PORT 8888  
  12. #define IP "192.168.3.51"  
  13.   
  14. void handler(int signo);  
  15.   
  16. int main()  
  17. {  
  18.     int listenfd, clientfd;  
  19.     int n;  
  20.     pid_t pid;  
  21.     struct sockaddr_in serveraddr,clientaddr;  
  22.     socklen_t peerlen;  
  23.     char buffer[BUFFER_SIZE];  
  24.   
  25.     if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)  
  26.     {  
  27.         perror("socket error");  
  28.         exit(-1);  
  29.     }  
  30.     else  
  31.     {  
  32.         printf("Socket successfully!\nlistenfd:%d\n",listenfd);  
  33.     }  
  34.   
  35.     memset(&serveraddr,0,sizeof(serveraddr));  
  36.     serveraddr.sin_family = AF_INET;  
  37.     serveraddr.sin_port = htons(PORT);  
  38.     serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  39.   
  40.     if(bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0)  
  41.     {  
  42.         perror("bind error");  
  43.         exit(-1);  
  44.     }  
  45.     else  
  46.     {  
  47.         printf("bind successfully!\n");  
  48.         printf("local IP:%s port:%d\n",IP,PORT);  
  49.     }  
  50.   
  51.     if(listen(listenfd,10) == -1)  
  52.     {  
  53.         perror("listen error");  
  54.         exit(-1);  
  55.     }  
  56.     else  
  57.     {  
  58.         printf("listening....\n");  
  59.     }  
  60.   
  61.     signal(SIGCHLD,handler);//捕捉SIGCHLD信号,子进程死亡后,调用handler回收      
  62.     peerlen = sizeof(clientaddr);  
  63.     while(1)  
  64.     {  
  65.         if((clientfd = accept(listenfd,(struct sockaddr *)&clientaddr,&peerlen)) < 0)  
  66.         {  
  67.             perror("accept error");  
  68.             exit(-1);  
  69.         }  
  70.         else  
  71.         {  
  72.             printf("connection from [%s:%d]\n",inet_ntoa(clientaddr.sin_addr)  
  73.                     ,ntohs(clientaddr.sin_port));     
  74.         }  
  75.   
  76.         memset(buffer,0,sizeof(buffer));  
  77.         if((pid = fork()) < 0)  
  78.         {  
  79.             perror("fork error");  
  80.             exit(-1);  
  81.         }  
  82.         else if(pid == 0)  
  83.         {  
  84.             close(listenfd);  
  85.             while(1)  
  86.             {  
  87.                 if((n = recv(clientfd,buffer,BUFFER_SIZE,0)) == -1)  
  88.                 {  
  89.                     perror("recv error");  
  90.                     exit(-1);  
  91.                 }  
  92.                 else if(n == 0)  
  93.                 {  
  94.                     break;  
  95.                 }  
  96.                 else  
  97.                 {  
  98.                     printf("Received message:%s\n",buffer);  
  99.                 }  
  100.               
  101.                 if(send(clientfd, buffer, n, 0) == -1)  
  102.                 {  
  103.                     perror("send error");  
  104.                     exit(-1);  
  105.                 }  
  106.                 else  
  107.                 {  
  108.                     printf("sendmessage:%s\n",buffer);  
  109.                 }  
  110.             }  
  111.             printf("client is closed\n");  
  112.             exit(0);  
  113.         }  
  114.         else  
  115.         {  
  116.             close(clientfd);  
  117.         }  
  118.     }  
  119.     close(listenfd);  
  120.   
  121.     return 0;  
  122. }  
  123. //接收到SIFCHLD信号后,回收子进程  
  124. void handler(int signo)  
  125. {  
  126.     pid_t pid;  
  127.     while((pid = waitpid(-1, NULL, WNOHANG)) > 0)  
  128.     {  
  129.         printf("child(%d) is over!\n",pid);  
  130.     }  
  131. }  

client

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <unistd.h>  
  5. #include <sys/socket.h>  
  6. #include <sys/types.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #define BUFFER_SIZE 128  
  10. #define PORT 8888  
  11.   
  12. int main()  
  13. {  
  14.     int n;  
  15.     int serverfd, clientfd;  
  16.     struct sockaddr_in serveraddr;  
  17.     char buffer[BUFFER_SIZE];  
  18.   
  19.     if((clientfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)  
  20.     {  
  21.         perror("socket error");  
  22.         exit(-1);  
  23.     }  
  24.     else  
  25.     {  
  26.         printf("clientfd:%d\n",clientfd);  
  27.     }  
  28.   
  29.     memset(&serveraddr,0,sizeof(serveraddr));  
  30.     serveraddr.sin_family = AF_INET;  
  31.     serveraddr.sin_port = htons(PORT);  
  32.     serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  33.   
  34.     if(connect(clientfd,(struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)  
  35.     {  
  36.         perror("connect error");  
  37.         exit(-1);  
  38.     }  
  39.     else  
  40.     {  
  41.         printf("connect successfully!\n");  
  42.     }  
  43.   
  44.     while(1)  
  45.     {         
  46.         printf("input > ");  
  47.         fgets(buffer,sizeof(buffer),stdin);  
  48.         if(strcmp(buffer,"quit\n") == 0)  
  49.             break;  
  50.         buffer[strlen(buffer) - 1] = '\0';  
  51.         if(send(clientfd,buffer,sizeof(buffer),0) == -1)  
  52.         {  
  53.             perror("send error");  
  54.             exit(-1);  
  55.         }  
  56.         memset(buffer,0,sizeof(buffer));  
  57.         if((n = recv(clientfd,buffer,sizeof(buffer),0)) == -1)  
  58.         {  
  59.             perror("recv error");  
  60.             exit(-1);  
  61.         }  
  62.         else if(n == 0)  
  63.         {  
  64.             break;  
  65.         }  
  66.         else  
  67.         {  
  68.             printf("echo:%s\n",buffer);  
  69.         }  
  70.     }  
  71.     close(clientfd);  
  72.   
  73.     return 0;  
  74. }  

执行结果如下:

client1:

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/netprogram/3$ ./client   
  2. clientfd:3  
  3. connect successfully!  
  4. input > I am client1!  
  5. echo:I am client1!  
  6. input > I am client1, how are you!  
  7. echo:I am client1, how are you!  
  8. input > quit  
  9. fs@ubuntu:~/qiang/netprogram/3$   

clinet2:

[cpp] view plaincopy
  1. fs@ubuntu:~$ telnet 192.168.3.51 8888  
  2. Trying 192.168.3.51...  
  3. Connected to 192.168.3.51.  
  4. Escape character is '^]'.  
  5. I am client2! I am telnet  
  6. I am client2! I am telnet  
  7. I am telnet, I am still alive!   
  8. I am telnet, I am still alive!  

server:

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/netprogram/3$ ./server   
  2. Socket successfully!  
  3. listenfd:3  
  4. bind successfully!  
  5. local IP:192.168.3.51 port:8888  
  6. listening....  
  7. connection from [127.0.0.1:45890]  
  8. Received message:I am client1!  
  9. sendmessage:I am client1!  
  10. connection from [192.168.3.51:35721]  
  11. Received message:I am client2! I am telnet  
  12.   
  13. sendmessage:I am client2! I am telnet  
  14.   
  15. Received message:I am client1, how are you!  
  16. sendmessage:I am client1, how are you!  
  17. client is closed  
  18. child(7216) is over!  
  19. Received message:I am telnet, I am still alive!  
  20.   
  21. sendmessage:I am telnet, I am still alive!  

可以看到实现了并发!

 

三、I/O多路复用并发服务器

        I/O多路复用模型可以解决资源限制的问题。此模型实际上时将UDP循环模型用在了TCP上面。服务器用单进程循环处理请求(客户端有限的情况下)。

但是,其存在同样的问题:由于服务器是依次处理客户的请求,所以可能会导致有的客户等待时间过长。

server:

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <unistd.h>  
  5. #include <sys/types.h>  
  6. #include <sys/socket.h>  
  7. #include <sys/select.h>  
  8. #include <netinet/in.h>  
  9. #include <arpa/inet.h>  
  10. #define PORT 8888  
  11. #define MAXSIZE 128  
  12.   
  13. int main()  
  14. {  
  15.     int i,nbyte;  
  16.     int listenfd, confd, maxfd;  
  17.     char buffer[MAXSIZE];  
  18.     fd_set global_rdfs, current_rdfs;  
  19.     struct sockaddr_in addr,clientaddr;  
  20.     int addrlen = sizeof(struct sockaddr_in);  
  21.     int caddrlen = sizeof(struct sockaddr_in);  
  22.   
  23.     if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)  
  24.     {  
  25.         perror("socket error");  
  26.         exit(-1);  
  27.     }  
  28.     else  
  29.     {  
  30.         printf("socket successfully!\n");  
  31.         printf("listenfd : %d\n",listenfd);  
  32.     }  
  33.   
  34.     memset(&addr, 0 ,addrlen);  
  35.     addr.sin_family = AF_INET;  
  36.     addr.sin_port = htons(PORT);  
  37.     addr.sin_addr.s_addr = htonl(INADDR_ANY);  
  38.     if(bind(listenfd,(struct sockaddr *)&addr,addrlen) == -1)  
  39.     {  
  40.         perror("bind error");  
  41.         exit(-1);  
  42.     }  
  43.     else  
  44.     {  
  45.         printf("bind successfully!\n");  
  46.         printf("listen port:%d\n",PORT);  
  47.     }  
  48.   
  49.     if(listen(listenfd,5) == -1)  
  50.     {  
  51.         perror("listen error");  
  52.         exit(-1);  
  53.     }  
  54.     else  
  55.     {  
  56.         printf("listening...\n");  
  57.     }  
  58.   
  59.     maxfd = listenfd;  
  60.     FD_ZERO(&global_rdfs);  
  61.     FD_SET(listenfd,&global_rdfs);  
  62.   
  63.     while(1)  
  64.     {  
  65.         current_rdfs = global_rdfs;  
  66.         if(select(maxfd + 1,&current_rdfs, NULL, NULL,0) < 0)  
  67.         {  
  68.             perror("select error");  
  69.             exit(-1);  
  70.         }  
  71.           
  72.         for(i = 0; i <= listenfd + 1; i++)  
  73.         {  
  74.             if(FD_ISSET(i, &current_rdfs)) //fd 就绪  
  75.             {  
  76.                 if(i == listenfd) //有新的连接  
  77.                 {  
  78.                     if((confd = accept(listenfd,(struct sockaddr *)&clientaddr,&caddrlen)) == -1)  
  79.                     {  
  80.                         perror("accept error");  
  81.                         exit(-1);  
  82.                     }  
  83.                     else  
  84.                     {  
  85.                         printf("Connect from [IP:%s PORT:%d]\n",  
  86.                                 inet_ntoa(clientaddr.sin_addr),clientaddr.sin_port);  
  87.                         FD_SET(confd,&global_rdfs);  
  88.                         maxfd = (maxfd > confd ? maxfd : confd);  
  89.                     }  
  90.                 }  
  91.                 else  
  92.                 {  
  93.                     if((nbyte = recv(i, buffer, sizeof(buffer),0)) < 0)  
  94.                     {  
  95.                         perror("recv error");  
  96.                         exit(-1);  
  97.                     }  
  98.                     else if(nbyte == 0) //客户端close  
  99.                     {  
  100.                         close(i);  
  101.                         FD_CLR(i,&global_rdfs); //将其清出  
  102.                     }  
  103.                     else  
  104.                     {  
  105.                         printf("recv:%s\n",buffer);  
  106.                         send(i, buffer, sizeof(buffer),0);  
  107.                     }  
  108.                 }  
  109.             }  
  110.         }  
  111.     }  
  112.   
  113.     return 0;  
  114. }  

这里使用多路连接TCP服务器,执行结果如下:

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/select$ ./select  
  2. socket successfully!  
  3. listenfd : 3  
  4. bind error: Address already in use  
  5. fs@ubuntu:~/qiang/select$ ./select2  
  6. socket successfully!  
  7. listenfd : 3  
  8. bind successfully!  
  9. listen port:8888  
  10. listening...  
  11. Connect from [IP:192.168.3.51 PORT:40075]  
  12. recv:xiao  
  13.   
  14. Connect from [IP:192.168.3.51 PORT:40331]  
  15. Connect from [IP:192.168.3.84 PORT:36233]  
  16. Connect from [IP:192.168.3.33 PORT:2499]  

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

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

相关文章

makefile中的patsubst, wildcard, notdir

From:http://blog.sina.com.cn/s/blog_60cbc1700100nuhz.html 1、wildcard : 扩展通配符 2、notdir &#xff1a; 去除路径 3、patsubst &#xff1a;替换通配符 例子&#xff1a; 建立一个测试目录&#xff0c;在测试目录下建立一个名为sub的子目录 $ mkdir test $ cd test $…

搭建实用深度学习环境(Ubuntu16.10+Theano0.8.2+Tensorflow0.11.0rc1+Keras1.1.0)

在动手安装之前&#xff0c;首先要确定硬件&#xff0c;系统&#xff0c;准备安装软件的版本&#xff0c;确定这些软硬件之间是否相互支持或兼容。本文安装的主要环境和软件如下&#xff1a; Ubuntu16.10CUDA8.0(cudnn5.1,CNMEM)Theano0.8.2Tensorflow0.11.0rc1Keras1.1.0 显卡…

Statspack安装心得

一&#xff0c;在win7下应该以管理员身份运行&#xff0c;sqlplusw 二&#xff0c;安装前要要执行如下代码&#xff0c;创建表空间 SQL> create tablespace perfstat 2datafile d:\oracle\oradata\eygle\perfstat.dbf 3size 500M 4extent management local; eygle为你的数据…

Linux 系统应用编程——网络编程(基础篇)

一、网络体系结构 1、OSI模型和TCP/IP 模型 网络体系结构指的是网络的分层结构以及每层使用的协议的集合。其中最著名的就是OSI协议参考模型&#xff0c;他是基于国际标准化组织&#xff08;OSI&#xff09;的建议发展起来的。它分为7个层次&#xff1a;应用层、表示层、会话层…

函数的定义与调用

1.理解函数 函数是一段代码块&#xff0c;它只定义一次&#xff0c;但可以被执行或调用任意次。函数可以有参数&#xff0c;实参&#xff08;argument&#xff09;和形参&#xff08;parameter&#xff09;&#xff0c;实参是在运行时的函数调用时传入的参数&#xff0c;形参是…

C++中函数的默认参数

使用方法&#xff1a; &#xff08;1&#xff09;在函数声明或定义时&#xff0c;直接对参数赋值&#xff0c;该参数就是默认参数。&#xff08;2&#xff09;在函数调用时&#xff0c;省略部分或全部参数&#xff0c;这时就会使用默认参数进行代替。注意事项&#xff1a; &…

Linux 系统应用编程——网络编程(socket编程)

二、网络编程基础 1、套接字概述 套接字就是网络编程的ID。网络通信&#xff0c;归根到底还是进程间的通信&#xff08;不同计算机上的进程间的通信&#xff09;。在网络中&#xff0c;每一个节点&#xff08;计算机或路由器&#xff09;都有一个网络地址&#xff0c;也就是IP地…

Linux 代码格式化工具 indent

以下是我最喜欢的代码格式化脚本&#xff1a; #!/bin/shif [ $# -lt 1 ]; thenecho "Usage: $0 <file>"exit 1fi# format a source file(*.c, *.h)formatSrcfile(){indent -npro -nip -lp -npsl -npcs -i4 -ts4 -sob -l140 -ss -nsaf -nsai -nsaw -bl -bli 0 $…

Android处理ListView中的Item中的Button按钮不能点击的问题

问题描述&#xff1a;ListView列表中的Button按钮按钮不能点击 解决办法&#xff1a;在ListView中的Item项的布局文件中加上&#xff1a;android:descendantFocusability"blocksDescendants"&#xff0c;问题解决。

php curl拉取远程图片

<?php $url "图片绝对地址/thumbnail.jpg"; $filename curl.jpg; getImg($url, $filename); /**通过curl方式获取制定的图片到本地* 完整的图片地址* 要存储的文件名*/ function getImg($url "", $filename "") {if(is_dir(basename($fi…

Linux 下 NFS服务的搭建

NFS是Network File System的简写&#xff0c;即网络文件系统。 网络文件系统是许多操作系统都支持的文件系统中的一种&#xff0c;也被成为NFS。NFS允许一个系统在网络上与他人共享目录和文件。通过使用NFS&#xff0c;用户可以像访问本地文件一样访问远端系统上的文件。 NFS所…

GCC 参数详解

From: http://www.cppblog.com/SEMAN/archive/2005/11/30/1440.html 先附上三篇相关文章&#xff1a; LINUX下的C编译器GCC简介 linux上的C/C编译器gcc/egcs详解 gcc和g的区别(很详细的描述) [介绍] gcc and g分别是gnu的c & c编译器 gcc/g在执行编译工作的时候&#…

电子客票状态整理

1.OPEN FOR USE&#xff1a;客票有效 2.VOID&#xff1a;已作废 3.REFUND&#xff1a;已退票 4.CHECK IN&#xff1a;正在办理登机 5.USED/FLOWN&#xff1a;客票已使用 6.SUSPENDED&#xff1a;系统处理&#xff0c;或人为挂起禁止使用该票 7.PRINT/EXCH&#xff1a;电子客票已…

Linux 系统应用编程——线程基础

传送门&#xff1a;Linux多线程编程实例解析 . linux多线程编程——同步与互斥 . 传统多任务操作系统中一个可以独立调度的任务&#xff08;或称之为顺序执行流&#xff09;是一个进程。每个程序加载到内存后只可以唯一地对应创建一个顺序执行流&#xff0c;即传统意义的进程。…

利用indent格式化源文件的脚本

脚本一&#xff1a;格式化指定目录下的源文件(*.h, *.cpp...) #!/bin/sh# 格式化某目录下所有*.h, *.c, *.cpp, *.hh文件, 并将文件换行符转换成Linux下的格式if [ $# -lt 1 ]; thenecho "Usage: $0 <dir>"exit 1elsedir$1fi# format a source file(*.c, *.h,…

apple mach-o linker (id) error

在网上查了下&#xff0c;有网友说是因为有变量重名&#xff0c;仔细检查了下代码&#xff0c;UIGraphicsEndImageContext()写成uigraphicsendimagecontext()了&#xff0c;改过来就编译通过了。转载于:https://www.cnblogs.com/cc-Cheng/p/3341242.html

Struts入门(三)深入Struts用法讲解

访问Servlet APIAction搜索顺序动态方法调用指定多个配置文件默认ActionStruts 后缀接收参数处理结果类型1.访问Servlet API 首先我们了解什么是Servlet API httpRequest、httpResponse、servletContext  3个api对应jsp面向对象&#xff1a;request、response、application …

linux errno定义

以下内容来自于Ubuntu系统&#xff0c;请看执行情况&#xff1a; [zcmasm-generic #6]$pwd /usr/include/asm-generic [zcmasm-generic #7]$ls errno* -lh -rw-r--r-- 1 root root 1.6K Jun 19 2013 errno-base.h -rw-r--r-- 1 root root 5.2K Jun 19 2013 errno.h [zcmasm-g…

linux多线程编程——同步与互斥

一、 为什么要用多线程技术&#xff1f; 1、避免阻塞&#xff0c;大家知道&#xff0c;单个进程只有一个主线程&#xff0c;当主线程阻塞的时候&#xff0c;整个进程也就阻塞了&#xff0c;无法再去做其它的一些功能了。 2、避免CPU空转&#xff0c;应用程序经常会涉及到RPC&am…

黑马程序员_泛型

--------------------ASP.NetAndroidIOS开发、.Net培训、期待与您交流&#xff01; -------------------- 1. 泛型 1.概述 泛型是为了解决了集合中存储对象安全问题&#xff0c;如果集合中存数了不同类型的对象&#xff0c;那么读取出来后&#xff0c;操作取出的对象以为不…