如何在C ++中创建RAW TCP / IP数据包?

时间:2020-03-05 18:57:28  来源:igfitidea点击:

我是一名刚开始的C ++程序员/网络管理员,但是我认为,如果有人将我指向正确的方向,我可以学习如何做。大多数教程都是使用旧代码进行演示的,由于某些原因,这些旧代码不再起作用。

因为我在Linux上,所以我只需要解释如何编写原始的Berkeley套接字。有人可以让我快速了解一下吗?

解决方案

回答

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

回答

首先阅读Beej的套接字编程指南。它将使我们快速掌握如何开始编写网络代码。之后,我们应该能够通过阅读手册页获得越来越多的信息。

其中大部分内容包括阅读我们喜欢的库的文档以及对手册页的基本理解。

回答

有很多参考资料(当然,想到了史蒂文斯的书),但是我发现《 Beej指南》对于入门非常有用。足够多的东西可以使我们了解真正的情况,但是它很简单,不需要花费几天的时间来编写" hello world" udp客户端/服务器。

回答

简单:

#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

...等等。

全部在sys / socket.h中

回答

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

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

回答

对于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服务器端:

设置一个插座

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

用listen开始在那个套接字上监听

致电接受以获取连接的客户端。 <-此时,我们将生成一个新线程来处理连接,同时进行另一个调用以接受下一个已连接的客户端。

一般沟通:

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

BSD套接字的源代码示例:

我们可以在Wikipedia上找到一些很好的示例代码。

进一步阅读:

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

4:

回答

张贴者,请澄清问题。

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

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

回答

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

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

有关该主题的权威参考,我们应该真正选择Stevens等人的Unix Network Programming,第1卷:套接字网络API(第3版)。

回答

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

回答

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

如果我们想退出C ++编程池,可以使用python。它使处理和传输TCP / IP数据包变得轻而易举。