急问关于setsockopt设置不成功

ineedu_cn 2005-01-06 09:25:22
我想得到本机接收到的所有IP包和发送一些包出去,且需要完整的IP头(因为要进行分析)。写了如下的代码:
WSADATA wsd;
if(WSAStartup(MAKEWORD(2,2),&wsd)){
MessageBox("不能装载Winsock2库");
return false;
}

SOCKET rawsock=-1;
if(socket(AF_INET,SOCK_RAW,IPPROTO_RAW)==INVALID_SOCKET){
MessageBox("无法构造rawsock");
closesocket(rawsock);
return false;
}

bool flag=true;
if(setsockopt(rawsock,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR){
int i=WSAGetLastError();
MessageBox("无法设置rawsock");
closesocket(rawsock);
return false;
}
每次执行到这里的时候都是弹出"无法设置rawsock",查看出错代码为10022,即WSAEINVAL:level is not valid, or the information in optval is not valid。
我把socket()的第三个参数改成IPPROTO_ICMP、IPPROTO_IP,都一样是setsockopt出错,代码10022,请问怎么会非法呢?msdn上是这样写的啊。
如果不设置IP_HDRINCL标记能不能得到完整的IP头的包呢?vc6,win2000pro环境下.
...全文
637 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ineedu_cn 2005-01-10
  • 打赏
  • 举报
回复
多谢,搞定了。
PPFish 2005-01-09
  • 打赏
  • 举报
回复
There are two types of socket options: Boolean options that enable or disable a feature or behavior, and options that require an integer value or structure. To enable a Boolean option, optval points to a nonzero integer. To disable the option optval points to an integer equal to zero. The optlen parameter should be equal to sizeof(int) for Boolean options. For other options, optval points to the an integer or structure that contains the desired value for the option, and optlen is the length of the integer or structure.

aspvbjava 2005-01-08
  • 打赏
  • 举报
回复
看不出毛病,下面的没问题,你对照一下,很可能是语法错误
WSADATA wd;
if(WSAStartup(MAKEWORD(2, 2), &wd) != 0){
fprintf(stderr, "WSAStartup return error %d\r\n", WSAGetLastError());
return;
}

if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == INVALID_SOCKET){
fprintf(stderr, "socket return error %d\r\n", WSAGetLastError());
return;
}

int flag = 1;
if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&flag, sizeof(flag)) == SOCKET_ERROR){
fprintf(stderr, "setsockopt IP_HDRINCL error %d\r\n", WSAGetLastError());
return;
}
PPFish 2005-01-08
  • 打赏
  • 举报
回复
int PASCAL FAR setsockopt( SOCKET s, int level, int optname,const char FAR* optval, int optlen);
有两种套接口的选项:一种是布尔型选项,另一种是整形或结构选项;对于布尔型选项,optlen应等于sizeof(int)
楼主应该把sizeof(flag)改为sizeof(int)就OK了,在我这已测试通过
iceheart 2005-01-08
  • 打赏
  • 举报
回复
bool flag = true <<=====>> int flag = 1;
(sizeof(flag) == sizeof(int)) ???
没试过,估计就是这里
好像是最后一个参数是缓冲区长度,不能小于4
zhouyong0371 2005-01-08
  • 打赏
  • 举报
回复
if((rawsock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW))==INVALID_SOCKET){
改正之后
你的代码没问题呀?
WSADATA wsd;
if(WSAStartup(MAKEWORD(2,2),&wsd)){
cout<< "不能装载Winsock2库" << endl;
return;
}

SOCKET rawsock=-1;
if((rawsock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW))==INVALID_SOCKET){
cout << "无法构造rawsock" << endl;
closesocket(rawsock);
return;
}

int flag =1;
if(setsockopt(rawsock,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR){
int i=WSAGetLastError();
cout << "无法设置rawsock" << endl;
closesocket(rawsock);
return;
}
ineedu_cn 2005-01-07
  • 打赏
  • 举报
回复
试过IPPROTO_IP,就连IPPROTO_UDP、TCP全部都试过了,还是不行。
ineedu_cn 2005-01-07
  • 打赏
  • 举报
回复
各位大佬,帮帮手啊。
aspvbjava 2005-01-07
  • 打赏
  • 举报
回复
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mstcpip.h>
aspvbjava 2005-01-07
  • 打赏
  • 举报
回复
IPPROTO_RAW?没听说过
改成IPPROTO_IP
ineedu_cn 2005-01-07
  • 打赏
  • 举报
回复
更不明白,为什么以上代码移到bc上编译,执行起来就没有问题。
ineedu_cn 2005-01-07
  • 打赏
  • 举报
回复
上面一句copy过来的时候写错了,应该是
if((rawsock=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))==INVALID_SOCKET){...}
兄弟们,给点面子,帮帮手吧。
《计算机网络》课程设计 题 目 数据包发送和接受程序的实现 学 院 计算机学院 2012年12月21日 数据包发送和接受程序的实现 一、设计题目与要求 1.设计题目 发送TCP数据包 2.设计要求 本设计的功能是填充一个TCP数据包,并发送给目的主机。 1)以命令行形式运行:SendTCP source_ip source_port dest_ip dest_port,其中SendTCP是程序名,source_ip为源端IP地址,source_port为源端口号 ,dest_ip为目的地址,dest_port为目的端口号。 2)其他的TCP头部参数请自行设定。 3)数据字段为"This is my homework of network,I am happy!"。 4)成功发送后在屏幕上输出"send OK"。 三、详细设计 本课程设计的目标是发送一个TCP数据包,可以利用原始套接字来完成这个工作。整 个程序由初始化原始套接字和发送TCP数据包两个部分组成。 当应用进程需要通过TCP发送时,它就将此应用层报文传送给执行TCP协议的传输实体 。TCP传输实体将用户数据加上TCP报头,形成TCP数据包,在TCP数据包上增加IP头部, 形成IP包。如图- 1显示的是TCP数据包和IP包得关系。TCP协议的数据传输单位称为报文段,其格式如图- 2所示。报文段报头的长度是20B~60B,选项部分长度最多为40B。TCP报文段主要包括以下 字段。 端口号:端口号字段包括源端口号和目的端口号。每个端口号的长度是16位,分别表 示发送该TCP包的应用进程的端口号和接收该TCP包的应用进程的端口号。 图-1 TCP数据包加上IP报头形成IP包 序号:长度为32位。由于TCP协议是面向数据流的,它所传送的报文段可以视为连续 的数据流,因此需要给每一字节编号。序号字段的"序号"指的是本报文段数据的第一个 字节的序号。 确认号:该字段的长度为32位,它表示接收端希望接收下一个TCP包的第一个字节的 序号。 报文长度:该字段长度为4位。TCP报文长度是以4B为一个单元来计算的,实际上报文 长度在20B~60B之间。因此这个字段的值在5~15之间。 图-2 TCP数据包头部的格式 保留:长度为6位,留做今后使用,目前全部置0. 控制:这个字段定义了6种不同的标志,每一个标志占一位,在同一时间可以设置一 位或多位。URG位为1时,表明应尽快把数据传送给应用程序,否则表明允许数据在缓存 中存放一段时间。RST位为1时,表明要强制切断连接。SYN位为1时,表明有确立连接的 请求,这时,把序号字段的初始值作为序号字段的值,以便开始通信。FIN位为1时,表 明发送放已经没有数据发送了。 窗口大小:长度为16位,指向必须紧急处理的数据的位置,因此最多能够传送的数据 为65535B。 紧急指针:该字段长度为16,指向必需紧急处理的位置,只有当标志URG=1时紧急指 针才生效。从TCP报头后面的报文数据开始,到紧急指针所指出长度的数据,就是必须紧 急处理的数据。 选项: 该字段可以多达40B,包括单字节选项和多字节选项。 校验和:该字段长度为16位,校验和的校验范围包括伪头部,TCP报头以及应用层来 的数据。其计算方法与IP协议头部校验和的计算方法一样。伪头部为12B,它本身并不是 TCP数据包的真头部,只是在计算校验和时,临时和TCP数据包连接在一起。伪头部的格 式如图-3所示 0 8 16 24 31 "源IP地址 " "目的IP地址 " "00000000 "协议号(6) "TCP长度 " 创建一个原始套接字,并设置IP头选项 SOCKET sock; sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP); 或者: sock=WSASoccket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED); 这里,设置了SOCK_RAW标志,表示我们声明的是一个原始套接字类型。 为使用发送接收超时设置,必须将标志位置位置为WSA_FLAG_OVERLAPPED。在本课程设计 中,发送TCP包时隐藏了自己的IP地址,因此我们要自己填充IP头,设置IP头操作选项。 其中flag设置为ture,并设定 IP_HDRINCL 选项,表明自己来构造IP头。 setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&Flag, sizeof(Flag)); int timeout=1000; setsockopt(sock, SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout, sizeof(timeout)); 在这里我们

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧