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

时间:2008-09-16 23:02:11

标签: c++ c sockets networking tcp

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

由于我在Linux上,所以我需要的是如何编写原始Berkeley套接字的解释。有人可以快点给我一个忙吗?

11 个答案:

答案 0 :(得分:13)

首先阅读Beej's guide on socket programming。它将使您快速了解如何开始编写网络代码。之后,您应该能够从阅读手册页中获取越来越多的信息。

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

答案 1 :(得分:10)

对于初学者来说,如果你用“原始”来澄清你的意思,那将会很有帮助。传统上,这意味着您希望自己制作所有第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版)。

答案 2 :(得分:6)

对于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套接字的源代码示例:

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

进一步阅读:

我强烈推荐this bookthis online tutorial

alt text

4

答案 3 :(得分:5)

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

答案 4 :(得分:3)

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

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

答案 5 :(得分:2)

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

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

答案 6 :(得分:1)

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

答案 7 :(得分: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 

...等

全部在sys / socket.h中

答案 8 :(得分:1)

海报,请澄清你的问题。

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

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

答案 9 :(得分:1)

阅读理查德史蒂文斯的Unix Network Programming。必须的。它解释了它是如何工作的,为您提供代码,甚至为您提供帮助方法。你可能想查看他的一些其他书籍。 Advanced Programming In The Unix Enviernment是Unix中低级编程的必备条件。我甚至不再在Unix堆栈上做东西了,这些书中的stuf仍然有助于我编码。

答案 10 :(得分:1)

Libpcap可以让你制作完整的数据包(第2层到第7层)并通过网络发送出去。听起来很有趣,但有一些警告。您需要创建所有适当的标头并自己完成所有校验和。 Libnet可以帮助解决这个问题。

如果你想离开C ++编程池,python会有scapy。它使制作和传输TCP / IP数据包变得微不足道。