modify ping sample for lib_fiber

This commit is contained in:
zhengshuxin 2017-08-16 10:50:37 +08:00
parent 83d366f16a
commit 50cec66b5a
4 changed files with 126 additions and 13 deletions

View File

@ -9,6 +9,10 @@ static int __delay = 10;
static int __timeout = 1000;
static int __benchmark = 0;
static int __show_reply = 0;
static int __show_timeout = 0;
static int __show_unreach = 0;
static void display_res(ICMP_CHAT *chat)
{
if (chat) {
@ -58,18 +62,90 @@ static void fiber_ping(ACL_FIBER *fiber acl_unused, void *arg)
acl_fiber_schedule_stop();
}
static void reply_callback(ICMP_PKT_STATUS *status acl_unused, void *arg)
{
if (__show_reply) {
ICMP_HOST *host = (ICMP_HOST *) arg;
printf("%s\r\n", host->dest_ip);
}
}
static void timeout_callback(ICMP_PKT_STATUS *status, void *arg)
{
if (__show_timeout) {
ICMP_HOST *host = (ICMP_HOST *) arg;
printf("timeout: from %s, %.2f ms\r\n", host->dest_ip, status->rtt);
}
}
static void unreach_callback(ICMP_PKT_STATUS *status acl_unused, void *arg)
{
if (__show_unreach) {
ICMP_HOST *host = (ICMP_HOST *) arg;
printf("unreach: from %st\r\n", host->dest_ip);
}
}
static void finish_callback(ICMP_HOST *host, void *arg acl_unused)
{
icmp_stat_host(host, 0);
}
static void fiber_pine_one(ACL_FIBER *fiber acl_unused, void *arg)
{
char *ip = (char*) arg;
ICMP_CHAT *chat = icmp_chat_create(NULL, 1);
ICMP_HOST *host = icmp_host_new(chat, ip, ip, __npkt, 64,
__delay, __timeout);
icmp_host_set(host, host, reply_callback, timeout_callback,
unreach_callback, finish_callback);
icmp_chat(host);
icmp_host_free(host);
icmp_chat_free(chat);
acl_myfree(ip);
if (--__nfibers == 0)
acl_fiber_schedule_stop();
}
static void usage(const char* progname)
{
printf("usage: %s -h help\r\n"
" -d delay[milliseconds]\r\n"
" -t timout[milliseconds]\r\n"
" -z stack_size\r\n"
" -f ip_list_file\r\n"
" -s show_result_list[timeout,reply,unreach]\r\n"
" -b benchmark [if > 0 dest will be ignored]\r\n"
" -n npkt dest1 dest2...\r\n", progname);
printf("example: %s -n 10 www.sina.com.cn www.qq.com\r\n", progname);
}
static void show_list(const char *s)
{
ACL_ITER iter;
ACL_ARGV *tokens = acl_argv_split(s, ",;: \t\r\n");
#define EQ !strcasecmp
acl_foreach(iter, tokens) {
const char *ptr = (const char *) iter.data;
if (EQ(ptr, "timeout"))
__show_timeout = 1;
else if (EQ(ptr, "reply"))
__show_reply = 1;
else if (EQ(ptr, "unreach"))
__show_unreach = 1;
}
acl_argv_free(tokens);
}
/* 当收到 SIGINT 信号(即在 PING 过程中用户按下 ctrl + c)时的信号处理函数 */
static void on_sigint(int signo acl_unused)
{
@ -80,11 +156,14 @@ int main(int argc, char* argv[])
{
char ch;
int i, stack_size = 16000;
char iplist[256];
signal(SIGINT, on_sigint); /* 用户按下 ctr + c 时中断 PING 程序 */
acl_msg_stdout_enable(1); /* 允许 acl_msg_xxx 记录的信息输出至屏幕 */
while ((ch = getopt(argc, argv, "hn:d:z:b:t:")) > 0) {
iplist[0] = 0;
while ((ch = getopt(argc, argv, "hn:d:z:b:t:f:s:")) > 0) {
switch (ch) {
case 'n':
__npkt = atoi(optarg);
@ -104,6 +183,12 @@ int main(int argc, char* argv[])
case 'b':
__benchmark = atoi(optarg);
break;
case 'f':
ACL_SAFE_STRNCPY(iplist, optarg, sizeof(iplist));
break;
case 's':
show_list(optarg);
break;
default:
break;
}
@ -119,6 +204,32 @@ int main(int argc, char* argv[])
for (i = 0; i < __benchmark; i++)
acl_fiber_create(fiber_ping, localhost, stack_size);
} else if (iplist[0]) {
ACL_ARGV *ips = acl_argv_alloc(10240);
ACL_FILE *fp = acl_fopen(iplist, "r");
ACL_ITER iter;
if (fp == NULL) {
printf("open file %s error %s\r\n",
iplist, acl_last_serror());
acl_argv_free(ips);
return 1;
}
while (!acl_feof(fp)) {
char line[256];
if (acl_fgets_nonl(line, sizeof(line), fp) == NULL)
break;
acl_argv_add(ips, line, NULL);
}
acl_fclose(fp);
acl_foreach(iter, ips) {
char *ip = acl_mystrdup((char*) iter.data);
acl_fiber_create(fiber_pine_one, ip, stack_size);
}
__nfibers = acl_argv_size(ips);
acl_argv_free(ips);
} else {
if (optind == argc) {
usage(argv[0]);

View File

@ -21,12 +21,12 @@ struct ICMP_STAT {
/**< ICMP 所发送的每个 PING 包之后的主机状态应答 */
struct ICMP_PKT_STATUS {
size_t reply_len; /**< 包回复的数据长度 */
char frome_ip[32]; /**< 源地址 */
char from_ip[32]; /**< 源地址 */
double rtt; /**< 往返时间(毫秒)(Round Trip Time) */
double rtt; /**< 往返时间(毫秒)(Round Trip Time) */
unsigned short seq; /**< 序列号(seq no) */
unsigned char ttl; /**< 生存时间(time to live) */
char status;
unsigned char ttl; /**< 生存时间(time to live) */
char status;
#define ICMP_STATUS_OK 0
#define ICMP_STATUS_UNREACH 1
#define ICMP_STATUS_TIMEOUT 2
@ -47,8 +47,8 @@ struct ICMP_HOST {
size_t nsent; /**< 已经发送给该目的主机包的个数 */
char enable_log; /**< 是否将响应包的信息记日志 */
ACL_RING host_ring; /**< 由此链入 ICMP_CHAT->host_head 链中 */
ACL_RING pkt_head; /**< 发送给目的主机数据包的链的链头 */
ACL_RING host_ring; /**< 由此链入 ICMP_CHAT->host_head 链中 */
ACL_RING pkt_head; /**< 发送给目的主机数据包的链的链头 */
ICMP_CHAT *chat; /**< 所属的通信对象 */
/**< 汇报发送包的响应包状态 */

View File

@ -98,13 +98,14 @@ void icmp_pkt_save(ICMP_PKT* to, const ICMP_PKT* from)
to->pkt_status.reply_len = from->pkt_status.reply_len;
to->pkt_status.rtt = stamp_sub(&from->stamp, &to->stamp);
to->pkt_status.ttl = from->pkt_status.ttl;
snprintf(to->pkt_status.frome_ip, sizeof(to->pkt_status.frome_ip),
"%s", from->pkt_status.frome_ip);
snprintf(to->pkt_status.from_ip, sizeof(to->pkt_status.from_ip),
"%s", from->pkt_status.from_ip);
to->pkt_status.status = ICMP_STATUS_OK;
}
int icmp_pkt_unpack(const ICMP_CHAT *chat, const char *buf, int bytes, ICMP_PKT *pkt)
int icmp_pkt_unpack(const ICMP_CHAT *chat, const char *buf,
int bytes, ICMP_PKT *pkt)
{
const IP_HDR *iphdr;
const ICMP_HDR *icmphdr;
@ -115,7 +116,8 @@ int icmp_pkt_unpack(const ICMP_CHAT *chat, const char *buf, int bytes, ICMP_PKT
iphdrlen = iphdr->h_len * 4 ; /* number of 32-bit words *4 = bytes */
if (bytes < iphdrlen + ICMP_MIN) {
acl_msg_error("Too few bytes from %s", inet_ntoa(chat->is->from.sin_addr));
acl_msg_error("Too few bytes from %s",
inet_ntoa(chat->is->from.sin_addr));
return (-1);
}
@ -145,7 +147,7 @@ int icmp_pkt_unpack(const ICMP_CHAT *chat, const char *buf, int bytes, ICMP_PKT
pkt->pkt_status.status = ICMP_STATUS_OK;
pkt->pkt_status.seq = icmphdr->seq;
pkt->pkt_status.ttl = iphdr->ttl;
snprintf(pkt->pkt_status.frome_ip, sizeof(pkt->pkt_status.frome_ip),
snprintf(pkt->pkt_status.from_ip, sizeof(pkt->pkt_status.from_ip),
"%s", inet_ntoa(chat->is->from.sin_addr));
return (0);
}

View File

@ -27,7 +27,7 @@ void icmp_stat_report(ICMP_PKT *pkt)
pkt->pkt_status.status = ICMP_STATUS_OK;
if (pkt->icmp_host->enable_log)
acl_msg_info("Reply from %s: bytes=%d time=%.3fms TTL=%d icmp_seq=%d status=%d",
pkt->pkt_status.frome_ip, (int) pkt->pkt_status.reply_len,
pkt->pkt_status.from_ip, (int) pkt->pkt_status.reply_len,
pkt->pkt_status.rtt, pkt->pkt_status.ttl,
pkt->pkt_status.seq, pkt->pkt_status.status);