- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试将 echo TCP 服务器实现为可加载的内核模块。
我应该使用 sock_create 还是 sock_create_kern?
我应该使用接受还是 kernel_accept?
我的意思是我应该使用 kernel_accept 是有道理的;但我不知道为什么。我不能在内核中使用普通套接字吗?
最佳答案
问题是,您正试图将 user space 应用程序硬塞到 kernel 中。
套接字(和文件等)是内核通过内核用户空间 API/ABI 提供给用户空间应用程序的东西。 一些 ,但不是全部,也有一个内核可调用,用于另一个内核希望使用提供给用户空间的东西的情况。
让我们看看内核源代码中 net/socket.c 中 socket()
或 accept()
系统调用的 Linux 内核实现;寻找 SYSCALL_DEFINE3(socket,
和 SYSCALL_DEFINE3(accept,
、 SYSCALL_DEFINE4(recv,
等。
(我建议您使用例如 Elixir Cross Referencer 在 Linux 内核源代码中查找特定标识符,然后在官方内核 Git 树之一在线查找实际代码;这就是我所做的,无论如何。)
请注意指针参数如何具有 __user
限定符:这意味着指向的数据必须驻留在用户空间中,并且函数最终将使用 copy_from_user()
/copy_to_user()
来检索或设置数据。此外,操作访问文件描述符表,它是进程上下文的一部分:通常只存在于用户空间进程的东西。
本质上,这意味着您的内核模块必须创建一个用户空间“进程”(足以满足使用内核接口(interface)时跨越用户空间-内核边界的要求)以至少“保存”内存和文件描述符。这是很多工作,最终,它不会比用户空间应用程序的性能更高。 (Linux 内核开发人员已经为此工作了数十年。有一些专有操作系统在“内核空间”中做事可能更快,但在 Linux 中并非如此。在用户空间做事的成本是一些上下文切换,可能还有一些内存副本(用于传输的数据)。)
特别是,TCP/IP 和 UDP/IP 接口(interface)(参见例如 UDP/IPv4 的 net/ipv4/udp.c)似乎没有任何用于内核端缓冲区的接口(interface)(除了直接访问位于内核内存中的 rx/tx 套接字缓冲区之外) )。
您可能听说过 TUX web server ,这是 Ingo Molnár 的子系统 patch to the Linux kernel。即使那不是“内核模块服务器”,而更像是用户空间进程可以用来实现主要在内核空间中运行的服务器的子系统。
提供 TCP/IP 和/或 UDP/IP 服务器的内核模块的想法就像试图用锤子拧螺丝一样。经过一段时间后,它会起作用,但结果不会很漂亮。
但是,对于回显服务器的特殊情况,它可能会在 IPv4(参见 net/ipv4/ )和/或 IPv6(参见 net/ipv6/ )之上,类似于 ICMP 数据包( net/ipv4/icmp.c , net/ipv6/icmp.c )。当且仅当你打算专注于内核端网络的东西时,我才会考虑这条路线,否则你学到的一切都是非常专业的,在实践中没有那么有用。
如果您需要为练习或其他东西实现内核端的某些东西,我建议您远离“应用程序”类型的想法(服务或类似的东西)。
相反,我强烈建议开发一个字符设备驱动程序,可能实现某种进程间通信层,最好是总线样式(即一个发送者,任意数量的接收者)。类似的东西有许多实际的实际用例(包括硬件驱动程序,以及像 kdbus 类型的东西这样的奇怪东西),所以你学到的任何东西都将适用于现实世界。
(事实上,一个回显字符设备——它简单地输出写入它的任何内容——是一个很好的第一个目标。虽然 LDD3 适用于 Linux 内核 2.6.10,但对于任何深入研究 Linux 内核开发的人来说,它应该是一本极好的读物。如果您使用更新的内核,请记住示例代码可能无法按原样编译,并且您可能需要对 Linux 内核 Git 存储库和/或内核源代码交叉引用器(如上面的 Elixir)进行一些研究。)
关于c - 在内核中使用 sock_create、accept、bind 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52804340/
在 HTTP 中,您可以在请求中指定您的客户端可以使用 accept header 接受响应中的特定内容,其值如 application/xml。内容类型规范允许您在内容类型中包含参数,例如chars
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 Improve th
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 3 年前。 Improve th
我的 RESTFul API 只能响应 JSON 编码的数据(即我所有的 header 都有 Content-Type: application/json)。如果请求具有不允许 JSON 的 Acce
我有 C linux TCP 客户端/服务器应用程序。我想出了一个奇怪的场景,但我不知道这个应用程序是否有任何后果。我有一个可以接受 N 个连接的服务器端,例如这个服务器将接受 100 个连接。在这种
我试图找出 的可能值范围接受 和 接受-联系 header 字段,但我在 RFC 中找不到完整列表。有谁知道他们在哪里?我经常看到 Accept: application/sdp;level=1,
在 TCP 套接字代码中,我们创建了 2 个套接字。第一个接受新连接,第二个接受来自客户端的数据并在新连接建立时创建。 TCP header 中的哪个控制位允许服务器知道将此段传递给 ServerSo
我可以设置 Request.Content-Type = ... , Request.Content-Length = ... 如何设置Accept和Accept-Language? 我想上传一个文件
假设A是服务器,B是客户端。 B 创建一个到服务器 A 的套接字 b 并 ServerSocket.accept() 创建一个相应的套接字 a 对于客户端 B 现在,如果服务器 A 关闭了 a 但客户
如果客户端connect()先于服务端accept()成功,那么客户端如何知道服务端accept()成功呢?如果在 connect() 成功和服务器 accept() 之间的时间间隔调用 send()
这是我的代码: void error(const char *msg) { perror(msg); exit(1); } void sServer::acceptClientConn
在我的 pom.xml 中有以下详细信息 org.codehaus.jackson jackson-core-asl 1.9.13
假设我有两个如下所示的端点: @GET @Path("/blah") @Produces(MIME_TYPE_1) public Thing getThing() { .... } @GET
我的 Controller : @RestController public class ClawerController { @RequestMapping("/hello"
我不想要可视化 merge 工具,我也不希望必须 vi 冲突文件并手动在 HEAD(我的)和导入的更改(他们的)之间进行选择。大多数时候,我要么想要他们的所有更改,要么想要我的所有更改。通常这是因为我
我正在使用 spring 4.1.1.RELEASE 并包括: pom 中的 jackson-core-asl 1.9.13 和 jackson-mapper-asl 1.9.13 来创建一个带有 R
我正在尝试开发自己的基于非阻塞 NIO 消息的通信库。我已经阅读了 1000 个关于它的教程和书籍章节,我认为最终我得到了一些可以在很少的同时连接下工作的东西。但是当我在服务器端共存许多连接时,我遇到
我正在尝试编写一个 Bind 元编程模板辅助元函数,将模板参数绑定(bind)到某物。 我有一个简单的模板元函数的工作实现: template struct MakePair { using
我使用 spring 构建 Restful API,当我访问以下方法时: // get the entity in DB by using id number @RequestMapping(
只是想知道是否有一种方法可以通过 ASP.NET Core 中的属性强制检查 HTTP header 值是否属于一组给定值(例如 application/json,应用程序/xml) 我知道有 Pro
我是一名优秀的程序员,十分优秀!