【问题标题】:Send data from linux kernel module从 linux 内核模块发送数据
【发布时间】:2017-10-04 19:46:46
【问题描述】:

我想通过 tcp 从我的 linux 内核模块发送一些数据。 我尝试使用来自 http://www.avrfreaks.net/sites/default/files/tcp-server-send-recv.c 的一些代码,但是代码太旧(它使用了旧的 linux 内核 api)。 另外,我试图理解https://github.com/abysamross/simple-linux-kernel-tcp-client-server/blob/master/network_server.c,但它对我来说太复杂了:)

我只想通过 tcp 向指定的 IP 地址发送一些小数据。我该怎么做?

【问题讨论】:

  • 模块只会发送数据? -- 你指出的例子是一个服务器的例子。如果需要发送数据,必须查看客户端示例。
  • 是的,我需要一个只发送数据的模块。客户端的实际代码很难找到,我认为可以修改服务器的代码。
  • 在同一个项目中检查client example,如果你重用一些函数,你必须理解和修改tcp_client_connect函数(第124-198行)。您可以重用sock_create 函数来创建连接套接字,tcp_client_send 用于发送数据,tcp_client_receive 用于接收响应。
  • 我尝试做一些类似的动作,但是没有成功。我应该怎么做? 1) 调用 sock_create() 2) 调用 tcp_client_send()?
  • 您遇到了什么问题? -- 该示例适用于内核模块。尝试仅修改客户端模块以发送您想要的数据。如果它编译,您可以加载到您正在运行的系统中。您可以检查内核日志中的模块消息和错误(检查 dmesg)。如果您有问题,您可以发送另一个问题,显示部分代码和错误消息。

标签: c linux sockets tcp linux-kernel


【解决方案1】:

检查同一项目中的client example。如果你可以重用一些函数,你必须理解和修改tcp_client_connect函数(第124-198行)。在该模块中,tcp_client_connect 连接在模块加载时创建连接,network_client_exit 在模块卸载时关闭连接。

tcp_client_connect 函数中:

  1. (第 144 行)它创建了一个套接字

     struct socket *conn_socket = NULL;
    
     ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &conn_socket);
    
  2. 然后,(第 153 到 155 行)它创建一个目标地址

     struct sockaddr_in saddr;                               /* a socket address */
    
     saddr.sin_family = AF_INET;                             /* for internet */
     saddr.sin_port = htons(PORT);                           /* using the port PORT */
     saddr.sin_addr.s_addr = htonl(create_address(destip));  /* and address destip */
    
  3. (第 157 行)它使用该地址打开套接字(以创建连接)

     int ret = -1;
    
     ret = conn_socket->ops->connect(conn_socket, (struct sockaddr *)&saddr\
                    , sizeof(saddr), O_RDWR);     
    
     /* if it gets a response and it is not "in progress" */
     if(ret && (ret != -EINPROGRESS))
     {
         /* error creating the socket*/
     }
    
  4. (第 166 到 168 行)它使用套接字发送消息。

    int len = 49;
    char reply[len+1];
    
    memset(&reply, 0, len+1);   /* sets 0s into all the string space */
    strcat(reply, "HOLA");      /* sets the message */
    
    tcp_client_send(conn_socket, reply, strlen(reply), MSG_DONTWAIT);
    
  5. (第 170 行)等待消息(暂时)

    DECLARE_WAIT_QUEUE_HEAD(recv_wait);
    
    /* wait for a response or for a timetout */
    wait_event_timeout(recv_wait,\
                    !skb_queue_empty(&conn_socket->sk->sk_receive_queue),\
                                                                    5*HZ);
    
  6. (第 180 到 190 行)获取响应。

    int len = 49;
    char response[len+1];
    
    /* if something has arrived */
    if(!skb_queue_empty(&conn_socket->sk->sk_receive_queue))
    {
        memset(&response, 0, len+1);
        tcp_client_receive(conn_socket, response, MSG_DONTWAIT);
    }
    

network_client_exit函数中,

  1. (第 239 到 240 行)它关闭了连接。

    /* if the socket has been created */
    if(conn_socket != NULL)
    {
            /* relase the socket */
            sock_release(conn_socket);
    }
    

【讨论】:

    猜你喜欢
    • 2018-02-28
    • 2012-05-17
    • 2011-12-29
    • 2020-12-27
    • 1970-01-01
    • 2019-05-18
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多