Openwrt ubox應用例子: 實現C/S網絡通信

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環境變量請根據自己實際情況修改。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章