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

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

因为我在Linux上,所以我需要的是如何编写原始Berkeley套接字的解释。 有人可以给我一个快速的运行吗?

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

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

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

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

有关该主题的权威参考,您应该选择Stevens等人的Unix网络编程,第1卷:套接字网络API(第3版)。

对于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开始侦听该套接字

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

一般沟通:

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

BSD套接字的源代码示例:

你可以在维基百科找到一些很好的示例代码。

进一步阅读:

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

替代文字

4 :

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

您可以像在常规C中那样执行此操作,在标准库中没有特定于C ++的方法。

我用来学习这个的教程是http://beej.us/guide/bgnet/ 。 这是我在环顾四周后找到的最好的教程,它给出了所描述的所有function的清晰示例和良好解释。

我过去一年一直在开发libtins 。 它是一个高级C ++数据包制作和嗅探库。

除非你想重新发明轮子并实现每个协议的内部,否则我建议你使用一些更高级别的库,它已经为你做了。

有很多参考文献(当然,史蒂文斯的书出现在脑海中),但我发现Beej指南对于入门非常有用。 它非常内容,你可以理解真正发生的事情,但它很简单,你不需要几天时间来编写一个’hello world’udp客户端/服务器。

海报,请澄清你的问题。

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

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

阅读Richard Stevens的Unix网络编程 。 必须的。 它解释了它是如何工作的,给你代码,甚至给你帮助方法。 你可能想查看他的一些其他书籍。 Unix中的高级编程Enviernment是Unix中低级编程的必备条件。 我甚至不再在Unix堆栈上做东西了,这些书中的stuf仍然有助于我编码。

Libpcap将允许您制作完整的数据包(第2层到第7层)并通过线路发送出去。 听起来很有趣,但有一些警告。 您需要创建所有适当的标头并自己完成所有校验和。 但是,Libnet可以为此提供帮助。

如果你想退出C ++编程池,那就是python的scapy 。 它使制作和传输TCP / IP数据包变得微不足道。

简单:

 #include  #include  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中