kernel_recvmsg在调用时崩溃内核

时间:2018-04-10 13:31:25

标签: sockets networking tcp server kernel

我想在linux内核空间下实现一个TCP服务器。它可以接受新连接,但是,在调用kernel_recvmsg接收数据时,内核会立即挂起。

#define BUFFSIZE 1024

int myserver(void)
{  

    struct socket *sock,*client_sock;  
    struct sockaddr_in s_addr;  
    unsigned short portnum=8888;  
    int ret=0;  

    memset(&s_addr,0,sizeof(s_addr));  
    s_addr.sin_family=AF_INET;  
    s_addr.sin_port=htons(portnum);  
    s_addr.sin_addr.s_addr=in_aton("192.168.0.70");  


    sock=(struct socket *)kmalloc(sizeof(struct socket),GFP_KERNEL);  
    client_sock=(struct socket *)kmalloc(sizeof(struct socket),GFP_KERNEL);  

    /*create a socket*/  
    ret=sock_create_kern(&init_net, AF_INET,SOCK_STREAM, IPPROTO_TCP,&sock);  

    /*bind the socket*/  
    ret=sock->ops->bind(sock,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));  
    if(ret<0){  
            printk("server: bind error\n");  
            return ret;  
    }  
    printk("server:bind ok!\n");  

    /*listen*/  
    ret=sock->ops->listen(sock,10);  
    if(ret<0){  
            printk("server: listen error\n");  
            return ret;  
    }  
    printk("server:listen ok!\n");  

    ret=sock->ops->accept(sock,client_sock,10);
    if(ret<0){  
            printk("server:accept error!\n");  
            return ret;  
    }  

    printk("server: accept ok, Connection Established\n");  

    /*kmalloc a receive buffer*/  
    char *recvbuf=NULL;  
    recvbuf=kmalloc(1024,GFP_KERNEL);  
    if(recvbuf==NULL){  
            printk("server: recvbuf kmalloc error!\n");  
            return -1;  
    }  
    memset(recvbuf, 0, sizeof(recvbuf));  

    /*receive message from client*/  
    struct kvec vec;  
    struct msghdr msg;  
    memset(&vec,0,sizeof(vec));  
    memset(&msg,0,sizeof(msg));  
    vec.iov_base=recvbuf;  
    vec.iov_len=1024;  
    msg.msg_flags=MSG_NOSIGNAL;
    msleep(1000);
/*hi, kernel hangs here!*/
    ret=kernel_recvmsg(client_sock,&msg,&vec,1,1024, msg.msg_flags);
    recvbuf[1023] = 0;
    printk("receive message:\n %s\n",recvbuf);  

    /*release socket*/  
    printk("release socket now\n");
    sock_release(client_sock);  
    sock_release(sock);  
    return ret;  
}  

static int server_init(void){  
    printk("server init:\n");  
    return (myserver());  
}  

以上是代码。以下句子挂起。我的内核版本是3.2.1。我使用kgdb来调试内核,gdb显示received signal SIGSEGV, Segmentation fault

ret=kernel_recvmsg(client_sock,&msg,&vec,1,1024, msg.msg_flags);   

1 个答案:

答案 0 :(得分:0)

我应该使用kernel_accept代替sock->ops->accept,因为kernel_accept会更多地初始化sock->ops

   ret=kernel_accept(sock,&client_sock,10);