欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Openwrt ubox应用例子: 实现C/S网络通信

程序员文章站 2022-06-09 18:02:45
...

ubox是Openwrt的一个帮助工具包, 包含了MD5,链表,平衡树,blob标签式二进制数据包的生成和解释......等等基础API, 以及uloop,usock,ustream,ulog等应用。 通过学习ubox可以更好地理解和融入Openwrt框架体系。

通过应用其中的uloop和usock可实现基于文件句柄监控和事件驱动机制的C/S结构网络通信应用。
以下是一个实现的小例子:

1.  服务端  usock_server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <libubox/usock.h>
#include <libubox/uloop.h>

static char *host_addr="192.168.1.9";
static char *server_port="5678";
static char *strhello="Welcome to UBOX world!\n";
static char *strreply="Add client to uloop_fd_event successfully!\n";

/*  client fd event call_back */
void sevent_cb(struct uloop_fd *fd, unsigned int events)
{
	char buf[1024];
	struct timeval tm;
	int ret;

	gettimeofday(&tm,NULL);

	if(events & ULOOP_READ) {
		printf("%ld: ULOOP_READ is triggered! sock fd=%d,  events=%d\n", tm.tv_sec,fd->fd, events);
		ret=read(fd->fd, buf, sizeof(buf));
		buf[ret]=0;
		printf("Client MSG: %s \n", buf);
		if(events & ULOOP_WRITE) {
			write(fd->fd, strhello, strlen(strhello));
		}
	}
}

/* server fd event call_back function */
void server_cb(struct uloop_fd *fd, unsigned int events)
{
	printf("server_cb is triggered! events=%d\n",events);
	int client_fd=accept(fd->fd, NULL,0);

	if(client_fd<0) {
		perror("server_cb accept");
		return;
	}

	printf(" >>>>>>> New client accepted! >>>>>>\n");
	write(client_fd,strhello,strlen(strhello));
	struct uloop_fd *ucli_fd=calloc(1,sizeof(struct uloop_fd));
	if(ucli_fd==NULL)
		return;

	/* add client fd to uloop event */
	ucli_fd->fd= client_fd;
	ucli_fd->cb = sevent_cb;
	printf("Add client to uloop_fd...\n");
	uloop_fd_add(ucli_fd, ULOOP_READ | ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
}

struct uloop_fd server_fd = {
	.cb = server_cb,
};

void main(void)
{
	int sfd;
	char buf[1024];

	/* 1. init uloop */
	uloop_init();

	/* 2. create server usock */
	sfd=usock(USOCK_TCP|USOCK_SERVER, host_addr, server_port);
	if(sfd<0) {
		perror("usock");
		exit(-1);
	}
	printf("Succeed to create server at %s:%s\n",host_addr, server_port);

	/* 3. add server fd to uloop event */
	server_fd.fd=sfd;
	uloop_fd_add(&server_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER); /* read only */

	/* 4. loop events monitoring */
	uloop_run();

	/* 5. end uloop */
	uloop_done();
}

2. 客户端  usock_client.c

#include <stdio.h>
#include <stdlib.h>
#include <libubox/usock.h>
#include <libubox/uloop.h>
#include <string.h>
#include <sys/time.h>

char *host_addr="192.168.1.9";
char *server_port="5678";
char *strhello="Hello UBOX!";

void cevent_cb(struct uloop_fd *fd, unsigned int events)
{
        char buf[1024];
	struct timeval tm;

	gettimeofday(&tm,NULL);

        if(events & ULOOP_READ) {
	        printf("%ld: event ULOOP_READ is triggered! sock fd=%d,  events=%d\n",tm.tv_sec, fd->fd, events);
                read(fd->fd, buf, sizeof(buf));
                printf("MSG from server: %s \n", buf);
	        if(events & ULOOP_WRITE) {
        	        write(fd->fd, strhello, strlen(strhello));
		}
		sleep(1);
        }
}

struct uloop_fd client_fd =
{
	.cb = cevent_cb,
};

void main(void)
{
	int cfd;
	char buf[1024];
	int ret;

	uloop_init();

	cfd=usock(USOCK_TCP, host_addr, server_port);
	if(cfd<0) {
		perror("usock");
		exit(-1);
	}
	printf("Connect to server %s:%s successfuly!\n", host_addr, server_port);

	ret=read(cfd, buf, sizeof(buf));
	buf[ret]=0;
	printf("receive msg: %s\n",buf);

	/* send a msg to trigger ping_pong events */
	write(cfd, strhello, strlen(strhello));

        client_fd.fd=cfd;
        uloop_fd_add(&client_fd, ULOOP_READ | ULOOP_WRITE );

        printf("start uloop_run() ...\n");
        uloop_run();

	uloop_done();
}

3. 本例子在openwrt  widora环境下编译通过, Makefile 如下:

export STAGING_DIR=/home/midas-zhou/openwrt_widora/staging_dir
COMMON_USRDIR=/home/midas-zhou/openwrt_widora/staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/usr/

CC= $(STAGING_DIR)/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mipsel-openwrt-linux-gcc

CFLAGS  += -I$(COMMON_USRDIR)/include
LDFLAGS += -L$(COMMON_USRDIR)/lib
LIBS    += -lubox

all:	 usock_server usock_client test_timeout

usock_server:   usock_server.c
	$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) usock_server.c -o usock_server

usock_client:   usock_client.c
	$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) usock_client.c -o usock_client

clean:
	rm -rf *.o usock_server usock_client

4. 在openwrt中试验, 首先运行usock_server,  然后启动若干个usock_client, 观察实际效果。

5. 备注:  程序中host_addr 和 Makefile环境变量请根据自己实际情况修改。

 

 

相关标签: Openwrt