ホストとIPが記載されたcsvファイルを読み込み、pingを複数スレッドで実行して結果を標準出力に出力します。
◆環境
OS |
debian 8.2
Linux TSV01 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u3 (2015-08-04) x86_64 GNU/Linux |
gcc |
4.9.2 (Debian 4.9.2-10) |
pingコマンドは、実行回数1回、タイムアウト5秒で実行します。
(1) pingが通った場合
# ping -c 1 -W 5 10.21.0.1
PING 10.21.0.1 (10.21.0.1) 56(84) bytes of data.
64 bytes from 10.21.0.1: icmp_seq=1 ttl=254 time=0.894 ms
--- 10.21.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.894/0.894/0.894/0.000 ms
(2) pingが通らない場合
# ping -c 1 -W 5 10.21.0.30
PING 10.21.0.30 (10.21.0.30) 56(84) bytes of data.
From 10.21.0.10 icmp_seq=1 Destination Host Unreachable
--- 10.21.0.30 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0m
s
本プログラムではpingの出力結果に「ttl=」という文字列が含まれていたら「pingが通った」と判断します。
ホストとIPが記載されたcsvファイルは、IP+,(カンマ)+ホスト名で記載します。
hostlist.txt
|
1:
2:
3:
4:
|
10.21.0.1,Gateway
10.21.0.10,Server
10.21.0.15,PC1
10.21.0.30,PC2
|
|
ホストcsvファイルを読み込むバッファを1024にしているため、それ以上のデータを記入されるとバッファオーバーフローすると思います。
実行時のパラメーターでホストcsvファイルを指定します。
# ./MultiPing hostlist.txt
Server 10.21.0.10 OK
PC1 10.21.0.15 OK
Gateway 10.21.0.1 OK
PC2 10.21.0.30 Unreachable
第2パラメーターに多重度を指定できます。
何も指定しないと10多重で処理が行われます。
# ./MultiPing hostlist.txt 2
Server 10.21.0.10 OK
Gateway 10.21.0.1 OK
PC1 10.21.0.15 OK
PC2 10.21.0.30 Unreachable
メインです。
MultiPing.c
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
|
/* 2016/09/24 1.0 新規作成 */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "MultiPing.h"
int main( int argc, char** argv )
{
// printf( "MultiPing_main start!!\n" );
if ( argc < 2 )
{
printf( "MultiPing <hostlist> [<threads number>]\n" );
exit( 1 );
}
int iMaxThreads = 10;
if ( argc == 3 )
{
iMaxThreads = atoi( argv[2] );
}
int i, j;
/* IPリストファイルを読み込む */
/* レイアウト:ホスト名,IPアドレス */
FILE *fp = fopen( argv[1], "r" );
if ( fp == NULL )
{
printf( "Host list not found!! %s", argv[1] );
exit( 2 );
}
HostInfo hi[HOST_LIMIT];
memset( hi, NULL, sizeof( hi ) );
int hiCnt=0;
for ( i = 0; ; i++ )
{
char buf[HOSTNAME_LEN+IP_LEN+1];
char *ret;
/* ファイルを1行読み込む */
memset( buf, 0x00, sizeof( buf ) );
ret = fgets( buf, sizeof( buf ), fp );
if ( ret == NULL )
{
break;
}
/* 改行コードを除去 */
for ( j = 0; j < ( int )strlen( buf ); j++ )
{
if ( ( ( unsigned char )buf[j] == '\r' )
|| ( ( unsigned char )buf[j] == '\n' )
)
{
buf[j] = NULL;
}
}
/* ,で区切り構造体配列へ格納する */
int iBufLen = strlen( buf );
for ( j = 0; j < iBufLen; j++ )
{
if ( ( unsigned char )buf[j] == ',' )
{
memcpy( hi[i].pIP, buf, j );
memcpy( hi[i].pHostName
, buf + j + 1
, iBufLen - j
);
break;
}
}
hiCnt++;
}
fclose( fp );
int iRunThreads = 0;
pthread_t *tid
= ( pthread_t* )malloc( sizeof( pthread_t ) * iMaxThreads );
int ret = 0;
int hiRun = 0;
for ( hiRun = 0; hiRun < hiCnt; )
{
/* スレッドを生成 */
iRunThreads = 0;
for ( j = 0; j < iMaxThreads; j++ )
{
/*
printf( "hi:%d/%s/%s<\n"
, hiRun
, hi[hiRun].pHostName
, hi[hiRun].pIP
);
*/
ret = pthread_create( &tid[j]
, NULL
, myThread
, ( void* )&hi[hiRun]
);
if ( ret != 0 )
{
/* スレッド生成失敗 */
printf( "pthread_create failed!!=[%d]\n", ret );
exit( -1 );
}
iRunThreads++;
// printf( "thread ID=[%ld]\n", tid[j] );
hiRun++;
if ( hiRun >= hiCnt )
{
/* HostInfoの件数(hiCnt)より実行件数(hiRun) */
/* の方が同じか大きい場合、処理はおしまい。 */
break;
}
}
/* 生成したスレッドの数だけスレッドの終了を待つ */
for ( j = 0; j < iRunThreads; j++ )
{
pthread_join( tid[j], NULL );
}
}
free( tid );
// printf( "MultiPing_main end!!\n" );
return 0;
}
|
|
ヘッダーファイルです。
MultiPing.h
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
|
#define HOSTNAME_LEN 64
#define IP_LEN 13
#define HOST_LIMIT 1024
typedef struct _HostInfo {
char pHostName[HOSTNAME_LEN+1];
char pIP[IP_LEN+1];
} HostInfo;
extern void* myThread( void* );
|
|
スレッド処理です。
MultiPing_threadMain.c
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
|
/* 2016/09/24 1.0 新規作成 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#include "MultiPing.h"
/* pingコマンドの出力結果を編集する */
char* searchWord( char* pBuf )
{
char* pos;
pos = strstr( pBuf, "ttl=" );
if ( pos != NULL )
{
return "OK\n";
}
return "Unreachable\n";
}
void* myThread( void* pParam )
{
// printf( "My Thread start!!\n" );
HostInfo* hi = ( HostInfo* )pParam;
// printf( "hi:%s/%s<\n", hi->pHostName, hi->pIP );
FILE* fp;
char cmd[256];
char buf[256];
char buf2[256];
memset( buf, 0x00, sizeof( buf ) );
// pingコマンド文字列の生成
memset( cmd, 0x00, sizeof( cmd ) );
sprintf( cmd, "ping -c 1 -W 5 %s", hi->pIP );
// コマンド実行
fp = popen( cmd, "r" );
int i = 0;
for ( i = 0; ; i++ )
{
// 実行結果を読み込む
if ( fgets( buf, 256, fp ) == NULL )
{
break;
}
if ( i != 1 )
{
// 2行目以外は検査しない
continue;
}
char* msg = searchWord( buf );
memset( buf2, 0x00, sizeof( buf2 ) );
sprintf( buf2
, "%s %s %s"
, hi->pHostName
, hi->pIP
, msg
);
( void )fputs( buf2, stdout );
}
( void )pclose( fp );
// printf( "My Thread end!!\n" );
/* スレッド終了 */
pthread_exit( 0 );
}
|
|
makefileです。
makefile
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
|
# 2016/09/24 (c) ymlib.com
TARGET = MultiPing
OBJS = MultiPing.o \
MultiPing_threadMain.o
CC = /usr/bin/gcc
$(TARGET): $(OBJS)
$(CC) -o $@ $(OBJS) -lpthread
.SUFFIXES: .c.o
.c.o:
$(CC) -Wall -c $< -g
clean:
rm -f $(TARGET) $(OBJS)
|
|
▲ PageTop ■ Home
Copyright (C) 2016 ymlib.com