⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ktcptest.c

📁 实现一个网卡到内存空间的零拷贝程序
💻 C
字号:
/* *  ktcptest.c *  Joris van Rantwijk, May 2001. * *  Linux kernel mode TCP performance test. * *  Parameters: *    ipaddr="127.0.0.1"	Destination IP address. *    port=9			Destination port number. *    bufsize=16384		Buffer size in bytes. *    count=1			Number of buffers to send. */#define __KERNEL__#define MODULE#define __KERNEL_SYSCALLS__#include <linux/stddef.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/malloc.h>#include <asm/uaccess.h>#include <linux/net.h>#include <linux/inet.h>#include <linux/socket.h>#include <linux/in.h>#include <linux/fcntl.h>#define MODNAME		"ktcptest"MODULE_AUTHOR("Joris van Rantwijk");MODULE_DESCRIPTION("Kernel mode TCP performance test");MODULE_PARM(ipaddr, "s");MODULE_PARM(port, "i");MODULE_PARM(bufsize, "i");MODULE_PARM(count, "i");static int port = 9;static const char * ipaddr = "127.0.0.1";static int bufsize = 16384;static int count = 1;static struct socket * makesocket(void){	struct socket *sock;	struct sockaddr_in saddr;	int err;	err = sock_create(PF_INET, SOCK_STREAM, 0, &sock);	if (err < 0)		return NULL;	saddr.sin_family = AF_INET;	saddr.sin_port = htons(port);	saddr.sin_addr.s_addr = in_aton(ipaddr);	err = sock->ops->connect(sock, (struct sockaddr *) &saddr,	                         sizeof(saddr), O_RDWR);	if (err < 0) {		sock_release(sock);		return NULL;	}	return sock;}static void closesocket(struct socket *sock){	sock_release(sock);}static int sendsocket(struct socket *sock, void *buf, size_t len,                      unsigned flags, struct sockaddr *addr, int addr_len){	struct msghdr msg;	struct iovec iov;	iov.iov_base = buf;	iov.iov_len = len;	msg.msg_iov = &iov;	msg.msg_iovlen = 1;	msg.msg_control = NULL;	msg.msg_controllen = 0;	msg.msg_name = addr;	msg.msg_namelen = addr_len;	msg.msg_flags = flags;	return sock_sendmsg(sock, &msg, len);}static void performance_test(void){	mm_segment_t oldfs;	struct socket *sock;	struct timeval tv_start, tv_done;	char *buf;	int i, err, transmitted;	int secs, usecs, msecs;	sock = makesocket();	if (sock == NULL) {		printk(MODNAME ": Cannot connect.\n");		return;	}	buf = kmalloc(bufsize, GFP_KERNEL);	if (buf == NULL) {		printk(MODNAME ": Cannot allocate buffer.\n");		closesocket(sock);		return;	}	printk(MODNAME ": Connected and ready for transmission.\n");	oldfs = get_fs();	set_fs(KERNEL_DS);	do_gettimeofday(&tv_start);	transmitted = 0;	for (i = 0; i < count; i++) {		err = sendsocket(sock, buf, bufsize, 0, NULL, 0);		if (err != bufsize) {			printk(MODNAME ": sendsocket returned %d.\n", err);			break;		}		transmitted += err;	}	do_gettimeofday(&tv_done);	secs = tv_done.tv_sec - tv_start.tv_sec;	usecs = tv_done.tv_usec - tv_start.tv_usec;	if (usecs < 0) { secs--; usecs += 1000000; }	msecs = secs * 1000 + usecs / 1000;	if (msecs == 0) msecs = 1;	set_fs(oldfs);	printk(MODNAME ": transmitted %d bytes in %d.%03d sec -> %d kB/s.\n",	       transmitted, secs, usecs / 1000, transmitted / msecs);	printk(MODNAME ": Done.\n");	kfree(buf);	closesocket(sock);}int init_module(void){	printk(MODNAME ": Entering init_module.\n");	printk(MODNAME ": ipaddr=%s port=%d bufsize=%d count=%d\n",	       ipaddr, port, bufsize, count);	performance_test();	printk(MODNAME ": Returning from init_module with EBUSY.\n");	return -EBUSY;}int cleanup_module(void){	printk(MODNAME ": cleanup_module\n");	return 0;}/* end */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -