1.1 实现内容
1. 功能
Ø 实现一个并发的echo服务器程序,它(接收端)将接收到字符串进行转换处理后,返回给发送端;允许有多个发送端同时存在;
Ø 字符串的处理包括:直接返回、全部转换为大写、全部转换为小写;处理方式应可以配置,配置方式包括全局(缺省)及每“发送-接收对(xmit/recv peer)”的。配置转换时,不应该影响正在处理的字符串;
Ø 为模拟处理过程的延时,接收端中每个字符转换添加200ms的延迟;
Ø 接收端中需统计其处理字符的数量,并且给外部提供命令形式的查询手段;
Ø 具备必要的例外处理,如内存不足等、client未关闭链接即意外退出等;
1.2 验收成果
1. 程序结构(应用专业方向)
Ø 以有链接的client-server方式实现echo程序
Ø 存在多个client,client与server在同一个系统中,它们之间采用domain socket或netlink socket相连;client之间没有关联
Ø client是一个程序的多个实例,而server只允许运行一个实例
2. 程序结构(内核专业方向)
Ø 内核模块作为接收端(服务器),而发送端(客户端)是用户空间的应用程序;
Ø 内核模块可动态加载与卸载
Ø 驱动相关组:
· 创建虚拟字符型设备,用于接受来自客户端的字符
· 使用ioctl控制接口来配置echo处理方式,ioctl的cmd自定义;
· 并发使用驱动的多实例来模拟;
Ø 非驱动相关组:
· 创建内核线程,作为内核中的server,用于,通信可采用netlink socket或其它可用的方式;
· 使用netlink接口来配置echo处理转换方式;
用户态netlink socket源码
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <linux/netlink.h>
#include <signal.h>
#define NETLINK_TEST 17
#define MSG_LEN 125
#define BUF_LEN 125
#define TIME 210
int skfd;
struct sockaddr_nl local;
struct sockaddr_nl dest;
struct nlmsghdr *message;
struct msg_to_kernel
{
struct nlmsghdr hdr;
char data[MSG_LEN];
};
struct u_packet_info
{
struct nlmsghdr hdr;
char msg[MSG_LEN];
};
static void sig_pipe(int sign)
{
printf("Catch a SIGPIPE signal\n");
close(skfd);
kill(local.nl_pid,SIGUSR1);
exit(-1);
}
int init_netlink(void)
{
//char *send_data = "aaaaaaaaaaaaBBBBBBBBBBBBBBBBBBaaaaaaaaaaaaaaaaBBBBBBBBBBBB11111112222";
char send_data[BUF_LEN];
message = (struct nlmsghdr *)malloc(1);
skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
if(skfd < 0){
printf("can not create a netlink socket\n");
return -1;
}
memset(&local, 0, sizeof(local));
local.nl_family = AF_NETLINK;
local.nl_pid = getpid();
local.nl_groups = 0;
if(bind(skfd, (struct sockaddr *)&local, sizeof(local)) != 0){
printf("bind() error\n");
return -1;
}
memset(&dest, 0, sizeof(dest));
dest.nl_family = AF_NETLINK;
dest.nl_pid = 0;
dest.nl_groups = 0;
memset(message, '\0', sizeof(struct nlmsghdr));
message->nlmsg_len = NLMSG_SPACE(MSG_LEN);
message->nlmsg_flags = 0;
message->nlmsg_type = 0;
message->nlmsg_seq = 0;
message->nlmsg_pid = local.nl_pid;
while(1) {
printf("input the data: ");
fgets(send_data, MSG_LEN, stdin);
if(0 == (strlen(send_data)-1))
continue;
else
break;
}
memcpy(NLMS