Linux 系统应用编程——网络编程(高级篇)

一、网络超时检测

        在网络通信过程中,经常会出现不可预知的各种情况。例如网络线路突发故障、通信一方异常结束等。一旦出现上述情况,很可能长时间都不会收到数据,而且无法判断是没有数据还是数据无法到达。如果使用的是TCP协议,可以检测出来;但如果使用UDP协议的话,需要在程序中进行相关检测。所以,为避免进程在没有数据时无限制的阻塞,使用网络超时检测很有必要。


1、套接字接收超时检测

        这里先介绍设置套接字选项的函数 setsockopt() 函数:

所需头文件#include <sys/types.h>
#include <sys/socket.h>
函数原型int setsockopt (int sockfd, int level, int optname, 
                              const void *optval, socklen_t optlen );
函数参数sockfd:套接字描述符
level:选项所属协议层
optval:保存选项值的缓冲区
optlen:选项值的长度
函数返回值成功:0
出错:-1,并设置 errno

下面是套接字常用选项及其说明:

LEVEL:SOL_SOCKET

选项名称说明数据类型
SO_BROADCAST允许发送广播数据int
SO_DEBUG允许调试int
SO_DONTRUOTE不查找路由int
SO_ERROR获得套接字错误int
SO_KEEPALIVE保持连接int
SO_LINGER延迟关闭连接struct linger
SO_OOBINLINE带外数据放入正常数据流int
SO_RCVBUF接收缓冲区大小int
SO_SNDBUF发送缓冲区大小int
SO_RCVTIMEO接收超时struct timeval
SO_SNDTIMEO发送超时struct timeval
SO_REUSERADDR允许重用本地地址和端口int
SO_TYPE获得套接字类型int

下面利用SO_RCVTIMEO的选项实现套接字的接收超时检测:

[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 <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #define N 64  
  10. #define PORT 8888  
  11.   
  12. int main()  
  13. {  
  14.     int sockfd;  
  15.     char buf[N];  
  16.     struct sockaddr_in seraddr;  
  17.     struct timeval t = {6, 0};  
  18.   
  19.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)  
  20.     {  
  21.         perror("socket error");  
  22.         exit(-1);  
  23.     }  
  24.     else  
  25.     {  
  26.         printf("socket successfully!\n");  
  27.         printf("sockfd:%d\n",sockfd);  
  28.     }  
  29.   
  30.     memset(&seraddr, 0, sizeof(seraddr));  
  31.     seraddr.sin_family = AF_INET;  
  32.     seraddr.sin_port = htons(PORT);  
  33.     seraddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  34.   
  35.     if(bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr)) == -1)  
  36.     {  
  37.         perror("bind error");  
  38.         exit(-1);  
  39.     }  
  40.     else  
  41.     {  
  42.         printf("bind successfully!\n");  
  43.         printf("PORT:%d\n",PORT);  
  44.     }  
  45.   
  46.     if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t)) < 0)  
  47.     {  
  48.         perror("setsockopt error");  
  49.         exit(-1);  
  50.     }  
  51.   
  52.     if(recvfrom(sockfd, buf, N, 0, NULL, NULL) < 0)  
  53.     {  
  54.         perror("fail to recvfrom");  
  55.         exit(-1);  
  56.     }  
  57.     else  
  58.     {  
  59.         printf("recv data: %s\n",buf);  
  60.     }  
  61.   
  62.     return 0;  
  63. }  

执行结果如下:

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/socket/time$ ./setsockopt   
  2. socket successfully!  
  3. sockfd:3  
  4. bind successfully!  
  5. PORT:8888  
  6. fail to recvfrom: Resource temporarily unavailable  
  7. fs@ubuntu:~/qiang/socket/time$   
可以看到,6s之内没有数据包到来,程序会从 recvfrom 函数返回,进行相应的错误处理。

注意:套接字一旦设置了超时之后,每一次发送或接收时都会检测,如果要取消超时检测,重新用setsockopt函数设置即可(把时间值指定为 0)。


2、定时器超时检测

       这里利用定时器信号SIGALARM,可以在程序中创建一个闹钟。当到达目标时间后,指定的信号处理函数被执行。这样同样可以利用SIGALARM信号实现检测,下面分别介绍相关数据类型和函数。

struct sigaction 是 Linux 中用来描述信号行为的结构体类型,其定义如下:

[cpp] view plaincopy
  1. struct sigaction  
  2. {  
  3.     void (*sa_handler) (int);  
  4.     void (*sa_sigaction)(int, siginfo_t *, void *);  
  5.     sigset_t sa_mask;  
  6.     int sa_flags;  
  7.     void (*sa_restorer) (void);  
  8. }  

①  sa_handler:此参数和signal()的参数handler相同,此参数主要用来对信号旧的安装函数signal()处理形式的支持;
②  sa_sigaction:新的信号安装机制,处理函数被调用的时候,不但可以得到信号编号,而且可以获悉被调用的原因以及产生问题的上下文的相关信息。
③  sa_mask:用来设置在处理该信号时暂时将sa_mask指定的信号搁置;
④  sa_restorer: 此参数没有使用;
⑤  sa_flags:用来设置信号处理的其他相关操作,下列的数值可用。可用OR 运算(|)组合:
                      ŸA_NOCLDSTOP:如果参数signum为SIGCHLD,则当子进程暂停时并不会通知父进程
                      SA_ONESHOT/SA_RESETHAND:当调用新的信号处理函数前,将此信号处理方式改为系统预设的方式
                      SA_RESTART:被信号中断的系统调用会自行重启
                      SA_NOMASK/SA_NODEFER:在处理此信号未结束前不理会此信号的再次到来
                      SA_SIGINFO:信号处理函数是带有三个参数的sa_sigaction。


所需头文件#include <signal.h>
函数原型int sigaction(int signum,  const struct sigaction *act ,
                                                       struct sigaction *oldact );
函数传入值signum:可以指定SIGKILL和SIGSTOP以外的所有信号
act        :act 是一个结构体,里面包含信号处理函数的地址、
                  处理方式等信息;
oldact  :参数oldact 是一个传出参数,sigaction 函数调用成功后,
                  oldact 里面包含以前对 signum 信号的处理方式的信息;
函数返回值成功:0
出错:-1

使用定时器信号检测超时的示例代码如下:

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <unistd.h>  
  5. #include <signal.h>  
  6. #include <sys/types.h>  
  7. #include <sys/socket.h>  
  8. #include <netinet/in.h>  
  9. #include <arpa/inet.h>  
  10. #define N 64  
  11. #define PORT 8888  
  12.   
  13. void handler(int signo)  
  14. {  
  15.     printf("interrupted by SIGALRM\n");  
  16. }  
  17.   
  18. int main()  
  19. {  
  20.     int sockfd;  
  21.     char buf[N];  
  22.     struct sockaddr_in seraddr;  
  23.     struct sigaction act;  
  24.   
  25.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)  
  26.     {  
  27.         perror("socket error");  
  28.         exit(-1);  
  29.     }  
  30.     else  
  31.     {  
  32.         printf("socket successfully!\n");  
  33.         printf("sockfd:%d\n",sockfd);  
  34.     }  
  35.   
  36.     memset(&seraddr, 0, sizeof(seraddr));  
  37.     seraddr.sin_family = AF_INET;  
  38.     seraddr.sin_port = htons(PORT);  
  39.     seraddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  40.   
  41.     if(bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr)) == -1)  
  42.     {  
  43.         perror("bind error");  
  44.         exit(-1);  
  45.     }  
  46.     else  
  47.     {  
  48.         printf("bind successfully!\n");  
  49.         printf("PORT:%d\n",PORT);  
  50.     }  
  51.   
  52.     sigaction(SIGALRM, NULL, &act);  
  53.     act.sa_handler = handler;  
  54.     act.sa_flags &= ~SA_RESTART;  
  55.     sigaction(SIGALRM, &act, NULL);  
  56.   
  57.     alarm(6);  
  58.     if(recvfrom(sockfd, buf, N, 0, NULL, NULL) < 0)  
  59.     {  
  60.         perror("fail to recvfrom");  
  61.         exit(-1);  
  62.     }  
  63.     printf("recv data: %s\n",buf);  
  64.     alarm(0);  
  65.   
  66.     return 0;  
  67. }  
执行结果如下:

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/socket/time$ ./alarm   
  2. socket successfully!  
  3. sockfd:3  
  4. bind successfully!  
  5. PORT:8888  
  6. interrupted by SIGALRM  
  7. fail to recvfrom: Interrupted system call  
  8. fs@ubuntu:~/qiang/socket/time$   


二、广播

        前面的网络通信中,采用的都是单播(唯一的发送方和接收方)的方式。很多时候,需要把数据同时发送给局域网中的所有主机。例如,通过广播ARP包获取目标主机的MAC地址。


1、广播地址

       IP地址用来标识网络中的一台主机。IPv4 协议用一个 32 位的无符号数表示网络地址,包括网络号和主机号。子网掩码表示 IP 地址中网络和占几个字节。对于一个 C类地址来说,子网掩码为 255.255.255.0。

        每个网段都有其对应的广播地址。以 C 类地址网段 192.168.1.x为例,其中最小的地址 192.168.1.0 代表该网段;而最大的地址192.168.1.255 则是该网段中的广播地址。当我们向这个地址发送数据包时,该网段中所以的主机都会接收并处理。

       注意:发送广播包时,目标IP 为广播地址而目标 MAC 是 ff:ff:ff:ff:ff。


2、广播包的发送和接收

广播包的发送和接收通过UDP套接字实现。

1)广播包发送流程如下:

创建udp 套接字

指定目标地址和端口

设置套接字选项允许发送广播包

发送数据包


发送广播包的示例如下:

[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 <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #define N 64  
  10. #define PORT 8888  
  11.   
  12. int main()  
  13. {  
  14.     int sockfd;  
  15.     int on = 1;  
  16.     char buf[N] = "This is a broadcast package!";  
  17.     struct sockaddr_in dstaddr;  
  18.   
  19.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)  
  20.     {  
  21.         perror("socket error");  
  22.         exit(-1);  
  23.     }  
  24.     else  
  25.     {  
  26.         printf("socket successfully!\n");  
  27.         printf("sockfd:%d\n",sockfd);  
  28.     }  
  29.   
  30.     memset(&dstaddr, 0, sizeof(dstaddr));  
  31.     dstaddr.sin_family = AF_INET;  
  32.     dstaddr.sin_port = htons(PORT);  
  33.     dstaddr.sin_addr.s_addr = inet_addr("192.168.1.255"); // 192.168.1.x 网段的广播地址  
  34.   
  35.     if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) //套接字默认不允许发送广播包,通过修改 SO_BROADCAST 选项使能  
  36.     {  
  37.         perror("setsockopt error");  
  38.         exit(-1);  
  39.     }  
  40.   
  41.     while(1)  
  42.     {  
  43.         sendto(sockfd, buf, N, 0,(struct sockaddr *)&dstaddr, sizeof(dstaddr));  
  44.         sleep(1);  
  45.     }  
  46.   
  47.     return 0;  
  48. }  


2)、广播包接收流程

广播包接收流程如下:

创建UDP套接字

绑定地址

接收数据包


接收包示例如下:

[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 <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #define N 64  
  10. #define PORT 8888  
  11.   
  12. int main()  
  13. {  
  14.     int sockfd;  
  15.     char buf[N];  
  16.     struct sockaddr_in seraddr;  
  17.     socklen_t peerlen = sizeof(seraddr);  
  18.   
  19.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)  
  20.     {  
  21.         perror("socket error");  
  22.         exit(-1);  
  23.     }  
  24.     else  
  25.     {  
  26.         printf("socket successfully!\n");  
  27.         printf("sockfd:%d\n",sockfd);  
  28.     }  
  29.   
  30.     memset(&seraddr, 0, sizeof(seraddr));  
  31.     seraddr.sin_family = AF_INET;  
  32.     seraddr.sin_port = htons(PORT);  
  33.     seraddr.sin_addr.s_addr = inet_addr("192.168.1.255"); //接收方绑定广播地址  
  34.   
  35.     if(bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr)) == -1)  
  36.     {  
  37.         perror("bind error");  
  38.         exit(-1);  
  39.     }  
  40.     else  
  41.     {  
  42.         printf("bind successfully!\n");  
  43.         printf("PORT:%d\n",PORT);  
  44.     }  
  45.   
  46.     while(1)  
  47.     {  
  48.         if(recvfrom(sockfd, buf, N, 0, (struct sockaddr *)&seraddr, &peerlen) < 0)  
  49.         {  
  50.             perror("fail to recvfrom");  
  51.             exit(-1);  
  52.         }  
  53.         else  
  54.         {  
  55.             printf("[%s:%d]",inet_ntoa(seraddr.sin_addr),ntohs(seraddr.sin_port));  
  56.             printf("%s\n",buf);  
  57.         }  
  58.     }  
  59.     return 0;  
  60. }  

执行结果如下

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/socket/guangbo$ ./guangbore   
  2. socket successfully!  
  3. sockfd:3  
  4. bind successfully!  
  5. PORT:8888  
  6. [127.0.0.1:56195]This is a broadcast package!  
  7. [127.0.0.1:56195]This is a broadcast package!  
  8. [127.0.0.1:56195]This is a broadcast package!  
  9. [127.0.0.1:56195]This is a broadcast package!  
  10. [127.0.0.1:56195]This is a broadcast package!  
  11. [127.0.0.1:56195]This is a broadcast package!  
  12. [127.0.0.1:56195]This is a broadcast package!  
  13. [127.0.0.1:56195]This is a broadcast package!  
  14. [127.0.0.1:56195]This is a broadcast package!  
  15. [127.0.0.1:56195]This is a broadcast package!  
  16. [127.0.0.1:56195]This is a broadcast package!  
  17.   
  18. ...  

3、组播

      通过广播可以很方便地实现发送数据包给局域网中的所有主机。但广播同样存在一些问题,例如,频繁地发送广播包造成所以主机数据链路层都会接收并交给上层 协议处理,也容易引起局域网的网络风暴。

      下面介绍一种数据包发送方式成为组播或多播。组播可以看成是单播和广播的这种。当发送组播数据包时,至于加入指定多播组的主机数据链路层才会处理,其他主机在数据链路层会直接丢掉收到的数据包。换句话说,我们可以通过组播的方式和指定的若干主机通信。


1、组播地址

IPv4 地址分为以下5类。

A类地址:最高位为0,主机号占24位,地址范围从 1.0.0.1到 126.255.255.254。

B类地址:最高两位为10,主机号占16位,地址范围从 128.0.0.1 到 191.254.255.254。

C类地址:最高3位为110,主机号占8位,地址范围从 192.0.1.1 到 223.255.254.254。

D类地址:最高4位为1110,地址范围从192.0.1.1到 223.255.254.254。

E类地址保留。

其中D类地址呗成为组播地址。每一个组播地址代表一个多播组。


2、组播包的发送和接收

组播包的发送和接收也通过UDP套接字实现。

1))组播发送流程如下:

创建UDP套接字

指定目标地址和端口

发送数据包


程序中,紧接着bind有一个setsockopt操作,它的作用是将socket加入一个组播组,因为socket要接收组播地址224.0.0.1的数据,它就必须加入该组播组。

结构体struct ip_mreq mreq是该操作的参数,下面是其定义:

[cpp] view plaincopy
  1. struct ip_mreq  
  2. {  
  3.     struct in_addr imr_multiaddr;   // 组播组的IP地址。  
  4.     struct in_addr imr_interface;   // 本地某一网络设备接口的IP地址。  
  5. };  
一台主机上可能有多块网卡,接入多个不同的子网,imr_interface参数就是指定一个特定的设备接口,告诉协议栈只想在这个设备所在的子网中加入某个组播组。有了这两个参数,协议栈就能知道:在哪个网络设备接口上加入哪个组播组。

发送组播包的示例代码如下:

[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 <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #define N 64  
  10. #define PORT 8888  
  11.   
  12. int main()  
  13. {  
  14.     int sockfd;  
  15.     char buf[N] = "This is a multicast package!";  
  16.     struct sockaddr_in dstaddr;  
  17.   
  18.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)  
  19.     {  
  20.         perror("socket error");  
  21.         exit(-1);  
  22.     }  
  23.     else  
  24.     {  
  25.         printf("socket successfully!\n");  
  26.         printf("sockfd:%d\n",sockfd);  
  27.     }  
  28.   
  29.     memset(&dstaddr, 0, sizeof(dstaddr));  
  30.     dstaddr.sin_family = AF_INET;  
  31.     dstaddr.sin_port = htons(PORT);  
  32.     dstaddr.sin_addr.s_addr = inet_addr("224.10.10.1"); //绑定组播地址  
  33.   
  34.     while(1)  
  35.     {  
  36.         sendto(sockfd, buf, N, 0,(struct sockaddr *)&dstaddr, sizeof(dstaddr));  
  37.         sleep(1);  
  38.     }  
  39.   
  40.     return 0;  
  41. }  


2)组播包接收流程

组播包接收流程如下

创建UDP套接字

加入多播组

绑定地址和端口

接收数据包


组播包接收流程如下:

[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 <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #define N 64  
  10. #define PORT 8888  
  11.   
  12. int main()  
  13. {  
  14.     int sockfd;  
  15.     char buf[N];  
  16.     struct ip_mreq mreq;  
  17.     struct sockaddr_in seraddr,myaddr;  
  18.     socklen_t peerlen = sizeof(seraddr);  
  19.   
  20.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)  
  21.     {  
  22.         perror("socket error");  
  23.         exit(-1);  
  24.     }  
  25.     else  
  26.     {  
  27.         printf("socket successfully!\n");  
  28.         printf("sockfd:%d\n",sockfd);  
  29.     }  
  30.   
  31.   
  32.     memset(&mreq, 0, sizeof(mreq));  
  33.     mreq.imr_multiaddr.s_addr = inet_addr("224.10.10.1"); //加入多播组,允许数据链路层处理指定组播包  
  34.     mreq.imr_interface.s_addr = htonl(INADDR_ANY);  
  35.     if(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)  
  36.     {  
  37.         perror("fail to setsockopt");  
  38.         exit(-1);  
  39.     }  
  40.   
  41.     memset(&seraddr, 0, sizeof(myaddr));//为套接字绑定组播地址和端口  
  42.     myaddr.sin_family = AF_INET;  
  43.     myaddr.sin_port = htons(PORT);  
  44.     myaddr.sin_addr.s_addr = inet_addr("224.10.10.1");  
  45.   
  46.     if(bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1)  
  47.     {  
  48.         perror("bind error");  
  49.         exit(-1);  
  50.     }  
  51.     else  
  52.     {  
  53.         printf("bind successfully!\n");  
  54.         printf("PORT:%d\n",PORT);  
  55.     }  
  56.   
  57.     while(1)  
  58.     {  
  59.         if(recvfrom(sockfd, buf, N, 0, (struct sockaddr *)&seraddr, &peerlen) < 0)  
  60.         {  
  61.             perror("fail to recvfrom");  
  62.             exit(-1);  
  63.         }  
  64.         else  
  65.         {  
  66.             printf("[%s:%d]",inet_ntoa(seraddr.sin_addr),ntohs(seraddr.sin_port));  
  67.             printf("%s\n",buf);  
  68.         }  
  69.     }  
  70.     return 0;  
  71. }  

执行结果如下:

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/socket/zubo$ ./zubore   
  2. socket successfully!  
  3. sockfd:3  
  4. bind successfully!  
  5. PORT:8888  
  6. [192.168.1.2:53259]This is a multicast package!  
  7. [192.168.1.2:53259]This is a multicast package!  
  8. [192.168.1.2:53259]This is a multicast package!  
  9. [192.168.1.2:53259]This is a multicast package!  
  10. [192.168.1.2:53259]This is a multicast package!  
  11. [192.168.1.2:53259]This is a multicast package!  
  12. [192.168.1.2:53259]This is a multicast package!  
  13. [192.168.1.2:53259]This is a multicast package!  
  14. [192.168.1.2:53259]This is a multicast package!  
  15.   
  16. ....  

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

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

相关文章

[win10] 在桌面上显示计算机、控制面板、网络

1. 右击桌面&#xff0c;选择个性化 2. 选择”主题", 点击“桌面图标设置” 3. 把想要放桌面的图标给钩上

linux下共享文件夹(windows可访问,linux也可访问)

2019独角兽企业重金招聘Python工程师标准>>> 本文是转字网上的两段&#xff0c;如果是菜鸟&#xff0c;想懂有点难度&#xff0c;我这里给点注释 在linux上共享文件夹windows下看 ******************************************* 首先给linux设一个ip&#xff0c;要和…

用nginx做了一下反向代理,得到的ip地址都是127.0.0.1

nginx反向代理配置时&#xff0c;一般会添加下面的配置&#xff1a; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; loc…

【windows】 设置开机启动程序

开始 -> 运行&#xff0c;输入&#xff1a;shell:startup 将要启动的“快捷方式”放入此目录下。重启生效&#xff01;

ssh时,密码输入框(密码输入提示)很晚才出现的解决方法

新配置了一台server&#xff08;centos6.2&#xff09;&#xff0c;发现从windows使用putty登录时&#xff0c;在输入用户名后总是很慢才提示输入密码[rootFDFS-1 ~]# ssh -V OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010发现ssh的版本较高了使用另一台linux服务器连接&…

Linux time()函数解析

time() 函数语法如下&#xff1a; 所需头文件#include <time.h>函数原型time_t time(time_t * timer)参数说明timerNULL时得到机器日历时间&#xff1b; timer时间数值时&#xff0c;用于设置日历时间&#xff1b;函数返回值机器日历时间 功能: 获取当前的系统时间&#…

开源|LightGBM:三天内收获GitHub 1000+ 星

原创 2017-01-05 LightGBM 微软研究院AI头条【导读】不久前微软DMTK(分布式机器学习工具包)团队在GitHub上开源了性能超越其他boosting工具的LightGBM&#xff0c;在三天之内GitHub上被star了1000次&#xff0c;fork了200次。知乎上有近千人关注“如何看待微软开源的LightGBM&a…

【phpstudy】在windows上开启后访问php页面显示502

phpstudy在windows上安装好后&#xff0c;会默认创建一个网站&#xff0c;而且使用了php7.3.4版本&#xff0c;但是当你把这个网站删除&#xff0c;再自己去手动(不利用它这个工具)创建一个php网站&#xff0c;会发现访问php页面会出现502错误&#xff0c;纠其原因&#xff0c;…

重设MYSQL数据库ROOT用户的密码

一、 在已知MYSQL数据库的ROOT用户密码的情况下&#xff0c;修改密码的方法&#xff1a;1、 在SHELL环境下&#xff0c;使用mysqladmin命令设置&#xff1a;mysqladmin –u root –p password “新密码” 回车后要求输入旧密码2、 在mysql>环境中,使用update命令&#xff0c…

Linux---进程调度相关命令解析

进程相关命令 1、ps 查看系统中的进程 使用方式&#xff1a;ps [options] [--help] 说明&#xff1a;显示瞬间进程 (process) 的动态 参数&#xff1a;ps的参数非常多, 在此仅列出几个常用的参数并大略介绍含义 ps命令常用用法&#xff08;方便查看系统进程&#xff09; 1&a…

随机数的扩展--等概率随机函数的实现

【转载】 Hackbuteer1的专栏 思想&#xff1a;就是先生成范围足够容纳扩展后随机数的一个随机数&#xff0c;然后忽略扩展过头的部分。 比如&#xff0c;已知random_n&#xff0c;要求random_m&#xff0c;最简单方法可以先生成random_n2()n*(random_n()-1)random_n(); 至于怎么…

js前台数据校验

1.脚本 Validator {exp:{numWord:/^[A-Za-z0-9]$/, //数字或字母numWordM:/^[\-]*[A-Za-z0-9]$/, //数字或字母可为负数letter:/^[A-Za-z]$/, //字母chinese:/^[\u4E00-\u9FA5\uF900-\uFA2D]$/,numberReg:/^[0-9]$/,//数字格式 只能是0到9的数字 eg:92wordReg:/^(\w|[\u4E00-\…

Linux 系统应用编程——多线程经典问题(生产者-消费者)

“生产者——消费者”问题是Linux多线程编程中的经典问题&#xff0c;主要是利用信号量处理线程间的同步和互斥问题。 “生产者——消费者”问题描述如下&#xff1a; 有一个有限缓冲区&#xff08;这里用有名管道实现 FIFO 式缓冲区&#xff09;和两个线程&#xff1a;生产者和…

Linux 文件服务---------- nfs Server

Linux 文件服务nfs &#xff08;Network file system&#xff09;#网络文件系统 ---> 远程文件调用samba #文件共享&#xff08;unix /linux /windows &#xff09; ,只能适用于局域网。ftp #远程文件存取.(跨网络&#xff0c; 跨平台&#xff0c; 文件存取)。 nfs Server r…

VC命令行编译参数介绍

From: http://blog.csdn.net/zhangxinrun/article/details/5797122 CL.exe是控制Microsoft C和C编译器与链接器的32位工具。编译器产生通用对象文件格式(COFF)对象(.obj)文件。链接器产生可执行文件(.exe)或动态链接库文件(DLL)。 注意&#xff0c;所有编译器选项都区分大小写。…

在linux 5上配置戴尔MD3220i

http://zh.community.dell.com/techcenter/storage/f/150/t/2773.aspx转载于:https://blog.51cto.com/xs2013/1298568

Linux 系统应用编程——进程间通信(下)

在前面&#xff0c;我们学习了传统的进程间通信方式——无名管道&#xff08;pipe&#xff09;、有名管道&#xff08;fifo&#xff09;和信号&#xff08;signal&#xff09;。 下面我们来学习 System V IPC 对象&#xff1a; 1、共享内存&#xff08;share memory&#xff0…

VC程序员常用工具篇

1. IDE&#xff1a;钟情于VC6.0&#xff0c;但是也感觉Visual Studio2008和2010的强大,可能迟早得转到VS高版本上来。在安装VC6.0的时候记得安装sp6补丁和msdn&#xff08;MSDN_1.5_精简安装版 &#xff09;2. 辅助&#xff1a; Visual Assist&#xff0c;喜欢它代码自动补全&a…

Hibernate的批量操作

批量插入 Hibernate强制开启了一级缓存&#xff0c;缓存空间是有限的&#xff0c;如果批量操作的SQL语句太多&#xff0c;就会运行失败&#xff08;内存溢出&#xff09;&#xff0c; 因此在批量操作的时候&#xff0c;每执行一批SQL语句&#xff0c;都需要刷新缓存&#xff0c…

.balignl 16,0xdeadbeef浅析

http://zqwt.012.blog.163.com/blog/static/12044684201031102956976/ 最近在分析u-boot的源代码&#xff0c;看到这一行&#xff1a; .balignl 16, 0xdeadbeef不知道为什么要这样写&#xff0c;0xdeadbeef&#xff0c;明显是个单词组&#xff0c;写在这里有何意义呢&am…