截獲所有以太網幀數據并進行具體分析

/* capture_packet.c - 截獲所有以太網幀數據并進行具體分析 *//* 常用函數的頭文件   */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>  
#include <strings.h>
#include <unistd.h>  
#include <signal.h>/* 與網絡相關的頭文件 */
#include <netinet/ip_icmp.h> 
#include <net/if_arp.h>
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>   
#include <netinet/ip.h>  
#include <netdb.h>  
#include <netinet/tcp.h>  
#include <netinet/udp.h> 
#include <signal.h>  
#include <net/if.h>  
#include <sys/ioctl.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <linux/if_ether.h> 
#include <net/ethernet.h>
#include <linux/igmp.h>
#include <netinet/tcp.h>/* 全局變量結構的結構體原型 - 包含要記錄的任何全局信息 */
struct global_info {unsigned int bytes;		/* 網卡接收的總字節數     */unsigned int packet_num;        /* 網卡接受的幀的總數量   */unsigned int packet_arp;        /* 接收到的arp包的數量    */unsigned int packet_rarp;       /* 接收到的rarp包的數量   */unsigned int packet_ip;		/* 接收到的ip包的數量     */unsigned int packet_icmp;	/* 接收到的icmp包的數量   */unsigned int packet_igmp;	/* 接收到的igmp包的數量   */unsigned int packet_tcp;	/* 接收到的tcp包的數量    */unsigned int packet_udp;	/* 接收到的udp包的數量    */int print_flag_frame;		/* 是否打印幀頭信息標志, 1表示打印, 0表示不打印 */int print_flag_arp;		/* 是否打印arp頭信息標志  */int print_flag_ip;		/* 是否打印ip頭信息標志   */int print_flag_rarp;		/* 是否打印rarp頭信息標志 */int print_flag_tcp;		/* 是否打印tcp頭信息標志  */int print_flag_udp;		/* 是否打印udp頭信息標志  */int print_flag_icmp;		/* 是否打印icmp頭信息標志 */int print_flag_igmp;		/* 是否打印igmp頭信息標志 */
};/* 定義一個全局變量,用于存儲全局信息 */
struct global_info global;struct ip_pair {unsigned int source_ip;unsigned int dest_ip;unsigned int count;
};/* 定義一個用于存儲ip對的結構體數組 */
struct ip_pair ip_pair[10000];/* 一個用于初始化全局信息的函數 */
void init_global( struct global_info  * var );/* 一個用于打印全局信息的函數   */
void print_global( struct global_info var );/* 打印一個錯誤,并退出 		*/
void error_and_exit( char * msg, int exit_code );/* 設置網卡成混雜模式	        */
int set_card_promisc( char * interface_name, int sock );/* 把mac地址轉換一個字符串      */
void mac_to_str( char * buf, char * mac_buf );/* 用于打印幫助信息 		*/
void help( void );/* 截獲網卡幀數據,并進行數據分用*/
void do_frame( int sockfd );  /* 處理ip層數據		        */
void do_ip( char * data );/* 打印ip頭信息 	        */
void print_ip( struct iphdr * );/* 處理arp層數據	       */
void do_arp( char * data );/* 打印arp頭信息 	       */
void print_arp( struct arphdr * ); /* 處理rarp數據		       */
void do_rarp( char * data );/* 處理tcp層數據 	       */
void do_tcp( char * data );/* 打印tcp層頭信息 	       */
void print_tcp( struct tcphdr * );/* 處理udp層數據 	       */
void do_udp( char * data );/* 打印udp層頭信息 	       */
void print_udp( struct udphdr * );/* 處理icmp層數據	       */
void do_icmp( char * data );/* 打印icmp頭信息	       */
void print_icmp( struct icmphdr * );/* 處理igmp層數據 	       */
void do_igmp( char * data );/* 打印igmp頭信息	       */
void print_igmp( struct igmphdr * );/* 初始化一個全局結構體 	      */
void init_global( struct global_info  * var )
{var->bytes = 0;var->packet_num = 0;var->packet_arp = 0;var->packet_rarp = 0;var->packet_ip = 0;var->packet_icmp = 0;var->packet_igmp = 0;var->packet_tcp = 0;var->packet_udp = 0;var->print_flag_frame = 0;var->print_flag_arp = 0;var->print_flag_ip = 0;var->print_flag_rarp = 0;var->print_flag_tcp = 0;var->print_flag_udp = 0;var->print_flag_icmp = 0;var->print_flag_igmp = 0;
}/* 一個用于打印全局信息的函數  */
void print_global( struct global_info var )
{printf("\n\n********** 全局信息 *****************\n\n");printf("總共接收字節數: %d kbytes.\n", var.bytes / 1024 );printf("總共接受包數量: %d\n\n", var.packet_num );if( var.packet_arp ) printf("接收 arp 包數量: %d\n", var.packet_arp );if( var.packet_rarp) printf("接收 rarp 包數量: %d\n", var.packet_rarp );if( var.packet_ip )  printf("接收 ip 包數量: %d\n", var.packet_ip );if( var.packet_icmp) printf("接收 icmp 包數量: %d\n", var.packet_icmp );if( var.packet_igmp) printf("接收 igmp 包數量: %d\n", var.packet_igmp );if( var.packet_tcp ) printf("接收 tcp 包數量: %d\n", var.packet_tcp );if( var.packet_udp ) printf("接收 udp 包數量: %d\n", var.packet_udp );printf("\n");
}/* 用于處理當下按ctrl-c時的處理函數 */
void sig_int( int sig )
{print_global( global );int i;/*for( i=0; i<global.packet_ip; i++ ){printf("%15s ==>> ", inet_ntoa( *(struct in_addr *)( &ip_pair[i].source_ip ) ) );printf("%15s \n", inet_ntoa( *(struct in_addr *)( &ip_pair[i].dest_ip ) ));}*/exit( 0 );
}/* 打印錯誤信息,并退出            */
void error_and_exit( char * msg, int exit_code )  
{  herror( msg );  exit( exit_code );  
}  /* 設置網卡模式成混帳模式,這樣的話可以截獲以太網幀數據 */
int set_card_promisc( char * interface_name, int sock )  
{  /* 用于套接口ioctl的接口請求結構體 	*/struct ifreq ifr; /* 復制網卡名稱進入請求結構體的名稱元素 */strncpy(ifr.ifr_name, interface_name ,strlen( interface_name )+1);  /* 通過ioctl獲得相應信息	        */if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) {       	error_and_exit("ioctl", 2);  }  /* 設置網卡模式標志為混雜模式	       */ifr.ifr_flags |= IFF_PROMISC;  		            /* 通過ioctl把參數傳遞給網卡	       */  if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 )  	      error_and_exit("ioctl", 3);  
}  /* 把mac地址轉換成字符串 */
void mac_to_str( char * buf, char * mac_buf )
{sprintf( mac_buf, "%02x:%02x:%02x:%02x:%02x:%02x",(unsigned char) *buf, (unsigned char)(*(buf+1)), (unsigned char)(*(buf+2)), (unsigned char)(*(buf+3)),(unsigned char)(*(buf+4)), (unsigned char)(*(buf+5)));mac_buf[17] = 0;
}void help( void )
{printf("Usage: capture [-h] [協議名稱 ...].\n");printf("默認情況: 打印所有包信息.\n");
}void print_udp( struct udphdr * pudp )
{printf("==================== udp 頭信息 ======================\n");printf("16位源端口號  : %d\n", ntohs( pudp->source ) );printf("16位目的端口號:	%d\n", ntohs( pudp->dest ) );printf("16位udp長度: %d\n", ntohs( pudp->len ) );printf("16位udp校驗和: %d\n", ntohs( pudp->check ) );if( ntohs( pudp->len ) != sizeof(struct udphdr ) && ntohs( pudp->len ) < 20 ){char * data = ( char * )pudp + sizeof( struct udphdr );printf("UDP數據: %s\n", data );}
}void do_udp( char * data )
{global.packet_udp ++;struct udphdr * pudp = ( struct udphdr * )data;if( global.print_flag_udp )print_udp( pudp );	
}void print_tcp( struct tcphdr * ptcp )
{printf("==================== tcp 頭信息 =====================\n");printf("源端口號  : %d\n", ntohs( ptcp->source ) );printf("目的端口號: %d\n", ntohs( ptcp->dest ) );printf("32位序列號  : %u\n", ntohl( ptcp->seq ) );printf("32位確認序號: %u\n", ntohl( ptcp->ack_seq ) );printf("首部長度: %d\n", ptcp->doff * 4 );printf("6個標志位: \n");printf("    緊急指針 urg : %d\n", ptcp->urg );printf("    確認序號位 ack : %d\n", ptcp->ack );printf("    接受方盡快將報文交給應用層 psh : %d\n", ptcp->psh );printf("    重建連接 rst : %d\n", ptcp->rst );printf("    用來發起連接的同步序號 syn : %d\n", ptcp->syn );printf("    發送端完成任務 fin : %d\n", ptcp->fin );printf("16位窗口大小: %d\n", ntohs( ptcp->window ) );printf("16位校驗和: %d\n", ntohs( ptcp->check ) );printf("16位緊急指針: %d\n", ntohs( ptcp->urg_ptr ) );if( ptcp->doff * 4 == 20 ){printf("選項數據: 沒有\n");} else {printf("選項數據: %d 字節\n", ptcp->doff * 4 - 20 );}char * data = ( char * )ptcp;data += ptcp->doff * 4;printf("數據長度: %d 字節\n", strlen(data) );if( strlen(data) < 10 )printf("數據: %s\n", data );
}void do_tcp( char * data )
{global.packet_tcp ++;struct tcphdr * ptcp;ptcp = ( struct tcphdr * )data;if( global.print_flag_tcp )	print_tcp( ptcp );
}void print_igmp( struct igmphdr * pigmp )
{printf("====================  igmp 包信息 ==========================\n");printf("igmp 版本: %d\n", pigmp->type & 15 );printf("igmp 類型: %d\n", pigmp->type >> 4 );printf("igmp 碼: %d\n", pigmp->code );printf("igmp 校驗和: %d\n", ntohs( pigmp->csum ) );printf("igmp 組地址: %d\n", ntohl( pigmp->group ) );
}void do_igmp( char * data )
{global.packet_igmp ++;struct igmphdr * pigmp = ( struct igmphdr * ) data;if( global.print_flag_igmp )print_igmp( pigmp );
}void print_icmp( struct icmphdr * picmp )
{printf("==================== icmp 包信息 ===========================\n");printf("消息類型: %d ", picmp->type );switch( picmp->type ){case ICMP_ECHOREPLY:printf("Ping的回顯應答\n");break;case ICMP_DEST_UNREACH:printf("目的不可達\n"); break;case ICMP_SOURCE_QUENCH:printf("源端被關閉\n");break;case ICMP_REDIRECT:printf("重定相\n");  break;case ICMP_ECHO:printf("ping的回顯請求\n");    break;case ICMP_TIME_EXCEEDED:printf("超時\n");break;case ICMP_PARAMETERPROB:printf("參數問題\n"); break;case ICMP_TIMESTAMP:printf("時間戳請求\n");   break;case ICMP_TIMESTAMPREPLY:printf("時間戳應答\n");   break;case ICMP_INFO_REQUEST:printf("信息請求\n");  break;case ICMP_INFO_REPLY:printf("信息應答\n"); break;case ICMP_ADDRESS:printf("地址掩碼請求\n"); break;case ICMP_ADDRESSREPLY:printf("地址掩碼應答\n"); break;default:printf("未知消息類型\n");break;}printf("消息類型的子選項: %d ", picmp->code );switch( picmp->type ){case ICMP_ECHOREPLY:printf("Ping的回顯應答\n");break;case ICMP_DEST_UNREACH:switch( picmp->type ){case ICMP_NET_UNREACH:printf("網絡不可到達\n"); break;case ICMP_HOST_UNREACH:printf("主機不可到達\n");  break;case  ICMP_PROT_UNREACH:printf("協議不可到達\n");break;  case  ICMP_PORT_UNREACH:printf("端口不可到達\n");break;case  ICMP_FRAG_NEEDED:printf("需要進行分片,但是又設置不分片位\n"); break;case  ICMP_SR_FAILED:printf("源站選路失敗\n"); break;case  ICMP_NET_UNKNOWN:printf("目的網絡不認識\n");break;case  ICMP_HOST_UNKNOWN:printf("目的主機不認識\n");break;case  ICMP_HOST_ISOLATED:printf("源主機北隔離\n");break;case  ICMP_NET_ANO:printf("目的網絡被強制禁止\n");break;case  ICMP_HOST_ANO:printf("目的主機被強制禁止\n");break;case  ICMP_NET_UNR_TOS:printf("由于服務類型TOS,網絡不可到達\n");break;case  ICMP_HOST_UNR_TOS:printf("由于服務類型TOS,主機不可到達\n");break;case  ICMP_PKT_FILTERED:printf("由于過濾,通信被強制禁止\n");break;case  ICMP_PREC_VIOLATION:printf("主機越權\n");break;case  ICMP_PREC_CUTOFF:printf("優先權中止生效\n");break;default:printf("未知代碼\n");break;}break;case ICMP_SOURCE_QUENCH:printf("源端被關閉\n");break;case ICMP_REDIRECT:switch( picmp->type ){case ICMP_REDIR_NET:printf("對網絡重定向\n");break;case ICMP_REDIR_HOST:printf("對主機重定向\n");   break;case ICMP_REDIR_NETTOS:printf("對服務類型和網絡重定向\n");  break;case ICMP_REDIR_HOSTTOS:printf("對服務類型和主機重定向\n"); break;defalut:printf("未知代碼\n");break;}break;case ICMP_ECHO:printf("ping的回顯請求\n");    break;case ICMP_TIME_EXCEEDED:switch( picmp->type ){case ICMP_EXC_TTL:printf("在傳輸期間生存時間為0\n");break;case ICMP_EXC_FRAGTIME:printf("在數據組裝期間生存時間為0\n"); break;default:printf("未知代碼\n");break;}break;case ICMP_PARAMETERPROB:switch( picmp->type ){case 0:printf("IP首部錯誤(包括各種差錯)\n");break;case 1:printf("缺少必須的選項\n");break;default:printf("原因未知\n"); break;}break;case ICMP_TIMESTAMP:printf("時間戳請求\n");   break;case ICMP_TIMESTAMPREPLY:printf("時間戳應答\n");   break;case ICMP_INFO_REQUEST:printf("信息請求\n");  break;case ICMP_INFO_REPLY:printf("信息應答\n"); break;case ICMP_ADDRESS:printf("地址掩碼請求\n"); break;case ICMP_ADDRESSREPLY:printf("地址掩碼應答\n"); break;default:printf("未知消息類型\n");break;}printf("校驗和: %d\n", ntohs(picmp->checksum) );
}void do_icmp( char * data )
{global.packet_icmp ++;struct icmphdr * picmp = ( struct icmphdr * ) data;if( global.print_flag_icmp )print_icmp( picmp );
}void print_ip( struct iphdr * iph )
{printf("=============== ip 頭信息 ===============\n");printf("IP 首部長度:%d\n", iph->ihl * 4 );printf("IP 版本    :%d\n", iph->version );printf("服務類型(tos): %d\n", iph->tos );printf("總長度字節: %d\n", ntohs(iph->tot_len) );printf("16位標識: %d\n", ntohs(iph->id) );printf("frag off: %d\n", ntohs(iph->frag_off) );printf("8位生存事件: %d\n", iph->ttl );printf("8位協議: %d\n", iph->protocol );printf("16位首部校驗和: %d\n", ntohs(iph->check) );printf("32位源IP地址  : %s\n", inet_ntoa( *(struct in_addr *)(&iph->saddr)) );printf("32位目的IP地址: %s\n", inet_ntoa( *(struct in_addr *)(&iph->daddr)) );}void ip_count( struct iphdr * iph )
{ip_pair[ global.packet_ip - 1 ].source_ip = iph->saddr;ip_pair[ global.packet_ip - 1 ].dest_ip = iph->daddr;
}void do_ip( char * data )
{global.packet_ip ++;struct iphdr *pip;         pip = ( struct iphdr * ) data;    /* pip = point to ip layer */if( global.print_flag_ip )print_ip( pip );ip_count( pip );char * pdata = data + pip->ihl * 4;switch( pip->protocol ){case IPPROTO_ICMP:do_icmp( pdata );break;case IPPROTO_IGMP:do_igmp( pdata );break;case IPPROTO_TCP:do_tcp( pdata );break;case IPPROTO_UDP:do_udp( pdata );break;default:printf("IP: 未知其上層協議.\n");break;}
}void print_arp( struct arphdr * parp )
{printf("硬件類型: %d ", ntohs(parp->ar_hrd) );switch( ntohs( parp->ar_hrd ) ){case ARPHRD_ETHER:printf("Ethernet 10/100Mbps.\n");	break;case ARPHRD_EETHER:printf("Experimental Ethernet.\n");break;case ARPHRD_AX25:printf("AX.25 Level 2.\n");break;case ARPHRD_PRONET:printf("PROnet token ring.\n");break;case ARPHRD_IEEE802:printf("IEEE 802.2 Ethernet/TR/TB.\n");break;case ARPHRD_APPLETLK:printf("APPLEtalk.\n");break;case ARPHRD_ATM:	printf("ATM.\n");						break;case ARPHRD_IEEE1394:printf("IEEE 1394 IPv4 .\n");break;default:printf("Unknow.\n");break;}printf("映射的協議地址類型: %d ", ntohs(parp->ar_pro) );switch( ntohs(parp->ar_pro) ){case ETHERTYPE_IP:printf("IP.\n");break;default:printf("error.\n");break;}printf("硬件地址長度: %d\n", parp->ar_hln );printf("協議地址長度: %d\n", parp->ar_pln );printf("操作碼: %d ", ntohs(parp->ar_op) );switch( ntohs(parp->ar_op) ){case ARPOP_REQUEST:printf("ARP 請求.\n");break;case ARPOP_REPLY:	printf("ARP 應答.\n");break;case ARPOP_RREQUEST:printf("RARP 請求.\n");break;case ARPOP_RREPLY:printf("RARP 應答.\n");break;case ARPOP_InREQUEST:printf("InARP 請求.\n");break;case ARPOP_InREPLY:printf("InARP 應答.\n");			break;case ARPOP_NAK:printf("(ATM)ARP NAK.\n");break;default:printf("arp 操作碼錯誤.\n");break;}char * addr = (char*)(parp + 1);char buf[18];mac_to_str( addr, buf ); printf("發送端以太網地址: %s\n", buf );printf("發送端IP地址:     %s\n", inet_ntoa( *(struct in_addr *)(addr+6) ));mac_to_str( addr+10, buf );printf("目的以太網地址: %s\n", buf );printf("目的IP地址:     %s\n", inet_ntoa( *(struct in_addr *)(addr+16) ));
}void do_arp( char * data )
{global.packet_arp ++;struct arphdr * parp;parp = ( struct arphdr * ) data;if( global.print_flag_arp ) {printf("============= arp 頭信息 ==============\n");print_arp( parp );}
}void do_rarp( char * data )
{global.packet_rarp ++;struct arphdr * parp;parp = ( struct arphdr * ) data;if( global.print_flag_rarp ){printf("============= rarp 頭信息 =============\n");print_arp( parp );}
}/* 打印以太網幀的包頭信息 */
void print_frame( struct ether_header * peth )
{/* 定義一個數組,用于存儲把mac地址轉換成字符串后的字符串 */char buf[ 18 ];printf("\n==================================   第 %d 個包  =======================================\n\n", global.packet_num );printf("==== 以太網幀信息 =====\n");char * shost = peth->ether_shost;mac_to_str( shost, buf );		printf("源以太網地址:  %s\n", buf );char * dhost = peth->ether_dhost;mac_to_str( dhost, buf );printf("目的以太網地址:%s\n", buf );
}/* 用于從網卡接受一幀數據,同時根據以太網協議字段傳遞數據給相應的上層協議處理 */
void do_frame( int sock )
{/* 用于存儲一幀數據         */char frame_buf[ 2000 ];/* 清空幀數據緩沖區	    */bzero( frame_buf, sizeof(frame_buf) );int len = sizeof( frame_buf );/* 用于存儲接受字節數       */int recv_num;/* 用于存儲發送方的地址信息 */struct sockaddr_in addr;/* 從網卡接收一幀數據       */recv_num = recvfrom( sock, (char *)frame_buf, sizeof( frame_buf ), 0, ( struct sockaddr * )&addr, &len );  /* 所接收的包的總數自加1    */global.packet_num ++;/* 從網卡接收的字節總數     */global.bytes += recv_num;/* 打印接收的包是第幾個包   *///printf("此幀數據長度: %d\n", recv_num );/* 定義一個用于指向以太網幀的指針 (這里我們只考慮最常見的以太網幀的情況) */struct ether_header * peth; /* 讓以太網頭指針指向從網卡接受到的幀的數據的開頭 */peth = (struct ether_header *)frame_buf; /* 傳遞以太網幀首地址給打印以太網幀信息的打印函數 */if( global.print_flag_frame )print_frame( peth );/* 定義一個數據指針,用于指向以太網幀的數據部分    */char * pdata;/* 讓 pdata 指向以太網幀的數據部分                */pdata = frame_buf + sizeof( struct ether_header );/* 根據以太網幀的協議字段進行數據分用 - 也就是進行數據拆封,根據協議字段調用相應層的處理函數 */switch( ntohs( peth->ether_type ) ){case ETHERTYPE_PUP:break;case ETHERTYPE_IP:do_ip( pdata );break;case ETHERTYPE_ARP:do_arp( pdata );break;case ETHERTYPE_REVARP:do_rarp( pdata );break;default:printf("Unkonw ethernet type  %d %x.\n", ntohs(peth->ether_type), ntohs(peth->ether_type) );break;}
}/* 主函數, 處理命令行輸入, 設置好全局變量, 并調用接受和處理幀的函數 */int main( int argc, char ** argv )  
{  /* 用于存儲套接口文件描述符 */int sockfd;/* 初始化全局變量 	  */init_global( &global );if( argc == 1 ) {       		/* 表示打印所有包頭信息 */global.print_flag_frame = 1;global.print_flag_arp = 1;global.print_flag_ip = 1;global.print_flag_rarp = 1;global.print_flag_tcp = 1;global.print_flag_udp = 1;global.print_flag_icmp = 1;global.print_flag_igmp = 1;} else {		       /* 幫助 或者 通過指定協議名稱只打印某層些協議 */if( !strcasecmp( argv[1], "-h" ) ){help();exit( 0 );} else { int i;for( i=1; i < argc; i++ ){if( !strcasecmp( argv[i], "frame" ) )global.print_flag_frame = 1;else if( !strcasecmp( argv[i], "arp" ) )global.print_flag_arp = 1;else if( !strcasecmp( argv[i], "rarp" ) )global.print_flag_rarp = 1;else if( !strcasecmp( argv[i], "ip" ) )global.print_flag_ip = 1;else if( !strcasecmp( argv[i], "tcp" ) )global.print_flag_tcp = 1;else if( !strcasecmp( argv[i], "udp" ) )global.print_flag_udp = 1;else if( !strcasecmp( argv[i], "icmp" ) )global.print_flag_icmp = 1;else if( !strcasecmp( argv[i], "igmp" ) )global.print_flag_igmp = 1;}}}/* 通過協議族AF_PACKET類信SOCK_RAW, 類型SOCK_RAW創建一個用于可以接受網卡幀數據的套接口,同時返回套就口文件描述符 */if( (sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) ) == -1 ) error_and_exit( "socket", 1 );  /* 如果發生錯誤,返回錯誤值, 并退出 *//* 設定網卡eth0成混雜模式 */set_card_promisc( "eth0", sockfd ); /* 設定信號處理函數, 下面是設置當我們按下ctrl-c時所調用的處理函數 */	signal( SIGINT, sig_int );/* 無限循環接收以太網卡數據幀, 并進行數據分用,直到你按下ctrl-c */while( 1 ){do_frame( sockfd );}  return 0;
}

  參考資料:

http://www.cnblogs.com/rollenholt/articles/2585432.html

http://www.binarytides.com/blog/c-packet-sniffer-code-with-libpcap-and-linux-sockets-bsd/

http://www.binarytides.com/blog/packet-sniffer-code-in-c-using-linux-sockets-bsd-part-2/

http://www.binarytides.com/blog/packet-sniffer-code-in-c-using-linux-sockets-bsd/

轉載于:https://www.cnblogs.com/rollenholt/archive/2012/07/11/2585633.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260665.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260665.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260665.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spark啟動程序:Master

臨時筆記def main(argStrings: Array[String]) {//讀取以spark.開頭的配置屬性val conf new SparkConf//檢查環境變量&#xff1a;SPARK_MASTER_HOST、SPARK_MASTER_PORT、SPARK_MASTER_WEBUI_PORT //再檢查配置屬性&#xff1a;master.ui.port //檢查其他master配置&am…

iOS - Frame 項目架構

前言 iOS 常見的幾種架構&#xff1a; 標簽式 Tab Menu列表式 List Menu抽屜式 Drawer瀑布式 Waterfall跳板式 Springborad陳列館式 Gallery旋轉木馬式 Carousel點聚式 Plus1、標簽式 優點&#xff1a; 1、清楚當前所在的入口位置2、輕松在各入口間頻繁跳轉且不會迷失方向3、直…

Windows 10下,anaconda (conda) 虛擬環境的創建,jupyter notebook如何使用虛擬環境

手把手教您創建conda 虛擬環境 1 安裝好anaconda后&#xff0c;會出現如下所示&#xff0c;這些都是anaconda集成啦&#xff0c;不需要再安裝了。我們在如下所指的anaconda Prompt右鍵&#xff0c;以管理員運行 2 打開后&#xff0c;這就是prompt&#xff0c;我們輸入pyth…

python下載文件傳到服務器_python實現FTP文件傳輸的方法(服務器端和客戶端)

用python實現FTP文件傳輸&#xff0c;包括服務器端和客戶端&#xff0c;要求 &#xff08;1&#xff09;客戶端訪問服務器端要有一個驗證功能 &#xff08;2&#xff09;可以有多個客戶端訪問服務器端 &#xff08;3&#xff09;可以對重名文件重新上傳或下載 FTP&#xff08;F…

oracle數據庫主鍵自增序列_Oracle數據庫序列詳解

前言&#xff1a;做過web開發的人員基本上都知道&#xff0c;數據庫表中的主鍵值有的時候我們會用數字類型的并且自增。這樣mysql、sql server中的都可以使用工具創建表的時候很容易實現。但是oracle中沒有設置自增的方法&#xff0c;一般情況我們會使用序列和觸發器來實現主鍵…

一步步學習微軟InfoPath2010和SP2010--第十三章節--SharePoint視圖和儀表板(9)--基于表單庫的儀表板...

現在你已經知道了如何將服務臺網站和表單與自定義視圖放在一起&#xff0c;最后一步是使用SharePoint創建儀表板&#xff0c;以呈現表單中的信息的基本報表。表單設計者經常致力于表單以至于他們忘記了SharePoint的力量來聚合表單的屬性&#xff0c;并建立KIPs和其他類型的報表…

SQL常用語句積累

SQL 常用語句積累&#xff1a;一、 SQL 基本語句SQL 分類&#xff1a;DDL —數據定義語言 (Create &#xff0c; Alter &#xff0c; Drop &#xff0c; DECLARE)DML —數據操縱語言 (Select &#xff0c; Delete &#xff0c; Update &#xff0c; Insert)DCL —數據控制語言 …

vscode 里 Import “numpy“ count not be resolved

問題如下&#xff1a; 我們分析一下這個問題&#xff0c;這里的問題。問題的翻譯是&#xff1a;導入"numpy"不能被解決。 這可能有幾個問題&#xff0c;1&#xff1a;vscode的python插件沒有安裝&#xff0c;2: vscode的python的解析器沒有設置好。 按照這個思路&…

xdocument查找節點值_二叉查找樹(java)

一棵二叉查找樹(BST)是一顆二叉樹&#xff0c;其中每個節點都含有一個Comparable的鍵且每個節點的鍵(以及相關的值)都大于其左子樹中的任意節點的鍵而小于右子樹的任意結點的鍵。數據表示和鏈表一樣&#xff0c;我們嵌套定義了一個私有類來表示二叉查找樹上的一個節點。每個節點…

三角形 畫_CAD入門基礎第3節:直角三角形的圓及如何修剪

這個軟件&#xff0c;仔細想想&#xff0c;無非就兩個命令&#xff0c;一是直線命令&#xff0c;二&#xff0c;就是圓。直線&#xff0c;無非也就是兩種&#xff0c;一&#xff0c;是水平直線和垂直于水平直線的豎線&#xff0c;二&#xff0c;就是各種斜線。第一種直線&#…

【轉】系統緩存全解析二:動態緩存(4)-第三方分布式緩存解決方案 Memcache(2)...

緩存系統MemCached的Java客戶端優化歷程&#xff08;轉載自http://code.google.com/p/memcache-client-forjava/。&#xff09;Memcached是一種集中式Cache&#xff0c;支持分布式橫向擴展。這里需要解釋說明一下&#xff0c;很多開發者覺得Memcached是一種分布式緩存系統&…

windows 10下搭建pyspark與遇到的一些問題的解決方法

目錄windows 10 下 搭建 pyspark所需要的工具過程與步驟windows 10 下 搭建 pyspark 所需要的工具 Java JDK 1.8.0 spark-2.2.0-bin-hadoop2.7 hadoop-2.7.3 winutils.exe 還需要有python環境&#xff0c;我用的是Anaconda 3&#xff08;默認你已經裝好此環境&#xff09;。…

Linux VNC server 安裝配置

1.安裝vnc server[rootpxe ~]# yum install tigervnc-server -y2.設置 vnc server 開機啟動[rootpxe ~]# chkconfig vncserver on3.修改vncserver 配置文件[rootpxe ~]# vi /etc/sysconfig/vncservers在配置文件后添加以下內容VNCSERVERS"2:root"VNCSERVERARGS[2]&qu…

為什么用python寫爬蟲_python-做爬蟲,如何避免牢獄之災

隨著數據資源的爆炸式增長&#xff0c;網絡爬蟲的應用場景和商業模式變得更加廣泛和多樣&#xff0c;網絡爬蟲技術為數據收集者提供了極大的便利&#xff0c;也給專業網絡爬蟲公司帶來巨大的收益。但是與之相伴的是許多人好奇的一件事——爬蟲是否違法&#xff1f; 關于這個問題…

vue跳轉頁面增加等待_vue跳轉頁面方法

1. router-link1. 不帶參數 //name,path都行, 建議用name // 注意&#xff1a;router-link中鏈接如果是/開始就是從根路由開始&#xff0c;如果開始不帶/&#xff0c;則從當前路由開始。 2.帶參數 // params傳參數 (類似post)// 路由配置 path: "/home/:id"…

開發HTML5手機游戲的5個注意要點--手機開發前景-- 轉

過去2年&#xff0c;我們都見證手機和社交游戲的興起&#xff1a;兩大游戲類型既各自發展&#xff0c;同時也開始互相滲透&#xff0c;融入HTML5技術。 手機社交游戲有自己的用戶基礎&#xff0c;日益蓬勃發展。 這個新興游戲類型兼容網頁社交游戲和本土應用的優點&#xff0c;…

棧(順序存儲)C++模板實現

#include <iostream> using namespace std;template <typename T> class stack{private:int top; //棧頂指針int maxLen; //棧最大長度T *data; //用數組來創建棧public:stack(int top_ -1 , int maxLen_ 10):top(top_),maxLen(maxLen_){data new T[maxLen]; …

java線程池參數含義

轉載自 http://blog.csdn.net/zhouhl_cn/article/details/7392607 感謝分享 項目中開發通常不會直接使用ThreadPoolExecutor&#xff0c;而是通過Executors.newFixedThreadPool()這種簡易寫法&#xff0c;創建適合自己項目的線程池。但是了解最基本的線程池ThreadPoolExecutor是…

第5章 Python 數字圖像處理(DIP) - 圖像復原與重建1 - 高斯噪聲

本章主要講圖像復原與重建&#xff0c;首先是了解一下各種噪聲的特點與模型&#xff0c;還有形成的方法。一些重點的噪聲&#xff0c;如高斯噪聲&#xff0c;均勻噪聲&#xff0c;伽馬噪聲&#xff0c;指數噪聲&#xff0c;還有椒鹽噪聲等。 本章主要的噪聲研究方法主要是加性噪…

十進制 轉換 2-10 進制,int的擴展方法

public static int ConvertToBase(this int i, int baseToConvertTo){if (baseToConvertTo < 2 || baseToConvertTo > 10){throw new ArgumentException("無法完成轉換" baseToConvertTo.ToString());}int resault 0; //存放結果int iterations 0; //十進…