getopt
getopt库是用来分析命令行参数的。由Unix标准库提供。 对类似于main函数那样传进来的参数进行解析。如有的参数是 –help 也可以 是-h,同时也可以传递参数,如 –interval 10。getopt可以支持-key 或者-k v。如果需要同时支持–key和-k,就需要用到getopt_long.
因为getopt_long可以支持长短两种参数格式,我们可以只使用这个函数。
相关函数表头文件
#include<unistd.h> #include <getopt.h>
函数声明
int getopt(int argc,char * const argv[ ],const char * optstring);
int getopt_long(int argc, char * const argv[], const char
*optstring, const struct option *longopts, int *longindex);
struct option {
const char *name; /* 参数名称 */
int has_arg; /* 指明是否带有参数 */
int *flag; /* flag=NULL时,返回value;不为空时,*flag=val,返回0 */
int val; /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */
};
变量和参数
比如char*optstring = “ab:c::”;表示
- 单个字符a 表示选项a没有参数 格式:-a即可,不加参数
- 单字符加冒号b: 表示选项b有且必须加参数 格式:-b 100或-b100,但-b=100错
- 单字符加2冒号c:: 表示选项c可以有,也可以无 格式:-c200,其它格式错误
example
#define _GNU_SOURCE
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <signal.h>
#include <getopt.h>
#include <sched.h>
#include <stdbool.h>
#define PORT 111
struct controll_blk
{
char role; /* 'c' lient or 's' erver */
int mode; /* 1 - server, 2 - client */
char *server_ip; /* -c option */
char *bind_address; /* first -B option */
int server_port;
};
const char usage[] = "Usage: newtest [-s|-c host] [options]\n"
" newtest [-h|--help]\n\n"
"Server or Client:\n"
" -p, --port # server port to listen on/connect to\n"
" -h, --help show this message and quit\n"
" -B, --bind <host> bind to the interface associated with the address <host>\n"
" -s, --server run in server mode\n"
" -c, --client <host> run in client mode, connecting to <host>\n"
;
void timer_set(int interval);
void timer_handler (int signum)
{
duration--;
}
void timer_init()
{
struct sigaction sa;
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGALRM, &sa, NULL);
}
void timer_set(int interval)
{
struct itimerval timer;
timer.it_value.tv_sec = interval;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &timer, NULL);
}
static inline void add_to_epfd(int fd, int type, int epfd)
{
struct epoll_event ev;
ev.data.fd = fd;
ev.events = type;
epoll_ctl(epfd, EPOLL_CTL_ADD, ev.data.fd, &ev);
}
int parse_arguments(struct controll_blk *test, int argc, char **argv)
{
static struct option longopts[] =
{
{"port", required_argument, NULL, 'p'},
{"server", no_argument, NULL, 's'},
{"client", required_argument, NULL, 'c'},
{"bind", required_argument, NULL, 'B'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
int flag;
int portno;
char *endptr;
char* slash;
test->pkt_size = 65536;
while ((flag = getopt_long(argc, argv, "p:sc:l:hP:n", longopts, NULL)) != -1) {
switch (flag) {
case 'p':
portno = atoi(optarg);
if (portno < 1 || portno > 65535) {
i_errno = IEBADPORT;
return -1;
}
test->server_port = portno;
break;
case 's':
if (test->role == 'c') {
i_errno = IESERVCLIENT;
return -1;
}
test->role = 's';
test->mode = 1;
break;
case 'c':
if (test->role == 's') {
i_errno = IESERVCLIENT;
return -1;
}
test->role = 'c';
test->mode = 2;
test->server_ip = strdup(optarg);
break;
case 'B':
test->bind_address = strdup(optarg);
test->mode = 1;
break;
case 'h':
printf("%s", usage);
exit(0);
default:
printf("%s", usage);
exit(1);
}
}
return 0;
}
int sever_proc(){
while(1)
{
}
}
int client_proc(){
connfd = socket(AF_INET, SOCK_STREAM, 0);
if (connect(connfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("connect failed: ");
continue;
}
add_to_epfd(connfd, EPOLLOUT, epfd);
timer_set(test.interval);
nfds = epoll_wait(epfd, events, 65536, eptimeout);
for (i = 0; i < nfds; i++) {
timer_set(test.interval);
bytes = write(events[i].data.fd, buffer, test.pkt_size);
}
for (i = 0; i < nsds; i++) {
close(sds[i]);
}
}
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char *buffer;
int epfd;
struct epoll_event *events;
unsigned long *r_bitmap;
unsigned long *w_bitmap;
int i;
int j;
int bytes;
struct controll_blk test;
size_t total = 0;
memset(&test, 0, sizeof(test));
if (parse_arguments(&test, argc, argv) < 0) {
printf(" error - %s\n");
exit(1);
}
memset(&serv_addr, '0', sizeof(serv_addr));
buffer = malloc(65536);
r_bitmap = (unsigned long *)malloc(sizeof(unsigned long) * 1024);
w_bitmap = (unsigned long *)malloc(sizeof(unsigned long) * 1024);
events = (struct epoll_event *)malloc(sizeof(struct epoll_event) * 10);
sds = (int *)malloc(sizeof(int) * 10);
epfd = epoll_create(1);
serv_addr.sin_family = AF_INET; // IPv4
if (test.bind_address) {
serv_addr.sin_addr.s_addr = inet_addr(test.bind_address);
} else {
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (test.server_ip) {
serv_addr.sin_addr.s_addr = inet_addr(test.server_ip);
}
}
serv_addr.sin_port = htons(test.server_port);
if (test.role == 's') {
listenfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 65536);
add_to_epfd(listenfd, EPOLLIN, epfd);
}
eptimeout = 1000;
timer_init();
last_duration = duration;
if (test.role == 's') {
server_proc();
} else {// C
client_proc();
}
}