24

我是一个初级 C++ 程序员/网络管理员,但我想如果有人指出我正确的方向,我可以学习如何做到这一点。大多数教程都是使用由于某种原因不再有效的旧代码进行演示的。

由于我在 Linux 上,所以我只需要解释如何编写原始伯克利套接字。有人可以让我快速运行吗?

4

12 回答 12

14

从阅读Beej 的套接字编程指南开始。它将带您快速了解如何开始编写网络代码。之后,您应该能够通过阅读手册页获得越来越多的信息。

其中大部分将包括阅读您最喜欢的库的文档,以及对手册页的基本了解。

于 2008-09-16T23:05:19.613 回答
11

对于初学者,如果您澄清“原始”的含义,将会很有帮助。传统上,这意味着您想要制作所有第 4 层标头(TCP/UDP/ICMP... 标头),也许还需要您自己制作一些 IP 标头。为此,您需要的不仅仅是 beej 的教程,我已经在这里提到了很多。在这种情况下,您希望在对套接字的调用中使用 SOCK_RAW 参数获得原始 IP 套接字(有关一些基础知识,请参见http://mixter.void.ru/rawip.html)。

如果您真正想要的只是能够与某个远程主机(例如 stackoverflow.com 上的端口 80)建立 TCP 连接,那么您可能不需要“原始”套接字,beej 的指南将为您提供很好的服务。

有关该主题的权威参考,您应该真正选择 Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition) by Stevens et al。

于 2008-09-16T23:19:59.547 回答
5

对于 TCP 客户端:

使用 gethostbyname 查找 dns 名称到 IP,它会返回一个 hostent 结构。我们称这个返回值为主机。

hostent *host = gethostbyname(HOSTNAME_CSTR);

填充套接字地址结构:

sockaddr_in sock;
sock.sin_family = AF_INET;
sock.sin_port = htons(REMOTE_PORT);
sock.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;

创建一个套接字并调用connect:

s = socket(AF_INET, SOCK_STREAM, 0); 
connect(s, (struct sockaddr *)&sock, sizeof(sock))

对于 TCP 服务器端:

设置一个套接字

使用绑定将您的地址绑定到该套接字。

用listen开始监听那个socket

调用 accept 以获取连接的客户端。<-- 此时,您生成一个新线程来处理连接,同时您再次调用接受以获取下一个连接的客户端。

一般通讯:

使用 send 和 recv 在客户端和服务器之间进行读写。

BSD套接字的源代码示例:

您可以在wikipedia找到一些很好的示例代码。

进一步阅读:

我强烈推荐这本书这个在线教程

替代文字

4

于 2008-09-16T23:13:20.920 回答
4

一个好的起点是使用Asio,它是一个用于网络通信的优秀跨平台(包括 Linux)库。

于 2008-09-16T23:05:01.627 回答
3

I've been developing libtins for the past year. It's a high level C++ packet crafting and sniffing library.

Unless you want to reinvent the wheel and implement every protocol's internals, I'd recommend you to use some higher level library which already does that for you.

于 2013-02-07T13:30:58.980 回答
3

执行此操作的方式与在常规 C 中完全相同,在标准库中没有特定于 C++ 的方式来执行此操作。

我用来学习的教程是http://beej.us/guide/bgnet/。这是我环顾四周后发现的最好的教程,它给出了清晰的示例,并很好地解释了它描述的所有功能。

于 2008-09-16T23:07:04.680 回答
1

对此有大量参考资料(当然,我想到了 Stevens 的书),但我发现Beej 指南对入门非常有用。它足够丰富,你可以理解真正发生的事情,但它足够简单,不需要你花几天时间来编写一个“hello world”udp 客户端/服务器。

于 2008-09-16T23:05:36.103 回答
1

简单的:

#include <sys/socket.h>
#include <sys/types.h>

int socket(int protocolFamily, int Type, int Protocol)
// returns a socket descriptor

int bind(int socketDescriptor, struct sockaddr* localAddress, unsigned int addressLength)
// returns 0 

...ETC。

都在 sys/socket.h

于 2008-09-16T23:06:11.203 回答
1

海报,请澄清你的问题。

几乎所有的回复似乎都认为您要的是套接字教程。我读到您的问题意味着您需要创建一个能够发送任意 IP 数据包的原始套接字。正如我在之前的回答中所说,一些操作系统限制了原始套接字的使用。

http://linux.die.net/man/7/raw “只有有效用户 ID 为 0 或 CAP_NET_RAW 能力的进程才允许打开原始套接字。”

于 2008-09-16T23:16:26.887 回答
1

阅读Richard Stevens 的Unix Network Programming。必须的。它解释了它是如何工作的,给你代码,甚至给你帮助方法。你可能想看看他的其他一些书。 Unix 环境中的高级编程对于 Unix中较低级别的编程来说是必须的。我什至不再在 Unix 堆栈上做任何事情,这些书中的内容仍然有助于我编写代码。

于 2008-09-16T23:30:47.087 回答
1

Libpcap将让您制作完整的数据包(第 2 层到第 7 层)并通过网络将它们发送出去。听起来很有趣,但有一些警告。您需要创建所有适当的标头并自己进行所有校验和。 不过, Libnet可以提供帮助。

如果你想摆脱 C++ 编程池,python 有scapy。它使制作和传输 TCP/IP 数据包变得轻而易举。

于 2009-02-27T16:38:17.243 回答
1

无论如何,如果您想使用 tcp/ip 堆栈,它们的标头将被添加到您的数据包中。如果你想控制数据包到字节,我建议你 npcap。不幸的是,Libpcap 已经过时了,尽管它更容易使用。但是,我个人使用过 npcap,它提供了对包的完全控制

于 2021-11-13T18:11:30.830 回答