C++ 为什么原始套接字sendto()函数在10022中失败?

C++ 为什么原始套接字sendto()函数在10022中失败?,c++,c,sockets,networking,tcp,C++,C,Sockets,Networking,Tcp,我正在VS2010下为ICMP、TCP、UDP等开发一个协议模糊器。我已通过原始套接字接口成功发送ICMP和UDP数据包。但是我在发送TCP时遇到了一个问题 我的环境:Windows 7 Ultimate x64,管理员帐户 这是我的方式: 我自己构造传输头和数据 2将原始套接字用于IPv4标头及其以下版本。RawConnect函数用于创建这样一个原始套接字。strIP是一个IP地址,strProtocol是需要指定的IP协议号,如ICMP为1、IGMP为2、TCP为6、UDP为17。因为我自己

我正在VS2010下为ICMP、TCP、UDP等开发一个协议模糊器。我已通过原始套接字接口成功发送ICMP和UDP数据包。但是我在发送TCP时遇到了一个问题

我的环境:Windows 7 Ultimate x64,管理员帐户

这是我的方式:

我自己构造传输头和数据

2将原始套接字用于IPv4标头及其以下版本。RawConnect函数用于创建这样一个原始套接字。strIP是一个IP地址,strProtocol是需要指定的IP协议号,如ICMP为1、IGMP为2、TCP为6、UDP为17。因为我自己没有构造IP头m_bSelfConstructIPHeader=FALSE,所以IP协议号是必需的。我不知道我用的对不对

3使用sendto函数发送缓冲区,返回-1,WSAGetLastError返回10022,这意味着提供的参数无效

下面是代码,谢谢

#include "stdafx.h"

#include "AFRawSocket.h"

#define IP_HDRINCL 2

AFRawSocket::AFRawSocket()
{
    m_socket = NULL;
    m_bSelfConstructIPHeader = FALSE;
}

CString AFRawSocket::itos(int i)
{
    CString strTemp;
    strTemp.Format(_T("%d"), i);
    return strTemp;
}

int AFRawSocket::stoi(CString s)
{
    return _wtoi(s);
}

//
// CStringAתCStringW
//
CStringW AFRawSocket::CStrA2CStrW(const CStringA &cstrSrcA)
{
    int len = MultiByteToWideChar(CP_ACP, 0, LPCSTR(cstrSrcA), -1, NULL, 0);
    wchar_t *wstr = new wchar_t[len];
    memset(wstr, 0, len*sizeof(wchar_t));
    MultiByteToWideChar(CP_ACP, 0, LPCSTR(cstrSrcA), -1, wstr, len);
    CStringW cstrDestW = wstr;
    delete[] wstr;

    return cstrDestW;
}

//
// CStringWתCStringA
//
CStringA AFRawSocket::CStrW2CStrA(const CStringW &cstrSrcW)
{
    int len = WideCharToMultiByte(CP_ACP, 0, LPCWSTR(cstrSrcW), -1, NULL, 0, NULL, NULL);
    char *str = new char[len];
    memset(str, 0, len);
    WideCharToMultiByte(CP_ACP, 0, LPCWSTR(cstrSrcW), -1, str, len, NULL, NULL);
    CStringA cstrDestA = str;
    delete[] str;

    return cstrDestA;
}

void AFRawSocket::SetSelfConstructIPHeader(BOOL bSelfConstructIPHeader)
{
    m_bSelfConstructIPHeader = bSelfConstructIPHeader;
}

BOOL AFRawSocket::RawConnect(CString strIP, CString strProtocol)
{
    int optval;
    CStringA straIP = CStrW2CStrA(strIP);

    int iProtocol;
    if (strProtocol == _T("N/A"))
    {
        iProtocol = 0;
    }
    else
    {
        iProtocol = stoi(strProtocol);
    }

    sockaddr_in mysock;
    ZeroMemory((char*)&mysock,sizeof(mysock));//初始化
    mysock.sin_family=AF_INET;
    mysock.sin_addr.s_addr=inet_addr(straIP);

    //Create Raw TCP Packet
    //printf("\nCreating Raw TCP Socket...");
    //ETH_P_ALL
    //AF_PACKET

//  if (iProtocol == IPPROTO_TCP)
//  {
//      iProtocol = IPPROTO_UDP;
//  }

    if((m_socket = socket(AF_INET, SOCK_RAW, iProtocol/*IPPROTO_RAW*/))==SOCKET_ERROR)
    {
        //printf("Creation of raw socket failed.");
        MyMessageBox_Error(_T("RawConnect"));
        return FALSE;
    }
    //printf("Raw TCP Socket Created successfully.");
    ////////////////////////////////////////////////

    if (m_bSelfConstructIPHeader)
    {
        //Put Socket in RAW Mode.
        //printf("\nSetting the socket in RAW mode...");
        if(setsockopt(m_socket, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
        {
            //printf("failed to set socket in raw mode.");
            MyMessageBox_Error(_T("RawConnect"));
            return FALSE;
        }
        //printf("Successful.");
        ////////////////////////////////////////////////
    }


//  //Target Hostname
//  printf("\nEnter hostname : ");
//  gets(host);
//  printf("\nResolving Hostname...");
//  if((server=gethostbyname(host))==0)
//  {
//      printf("Unable to resolve.");
//      return 0;
//  }
    ZeroMemory(&m_dest, sizeof(m_dest));
    m_dest.sin_family = AF_INET;
    //m_dest.sin_port   = htons(0);  //your destination port
    m_dest.sin_addr.s_addr=inet_addr(straIP);
    //m_dest.sin_addr.s_addr=inet_addr("8.8.8.8");
    //m_dest.sin_addr.s_addr=inet_addr("202.112.128.50");
    //memcpy(&m_dest.sin_addr.s_addr,&mysock.sin_addr.s_addr,4);
    //printf("Resolved.");
    /////////////////////////////////////////////////

//  if (bind(m_socket, (SOCKADDR *) &m_dest, sizeof(m_dest)) < 0)
//  {
//      int iError = WSAGetLastError();
//      MyMessageBox_Error(_T("RawConnect"));
//      return FALSE;
//  }

    return TRUE;
}

void AFRawSocket::RawSend(LPBYTE lpBuffer, DWORD dwSize)
{
    int iRet = sendto(m_socket , (const char *) lpBuffer, dwSize, 0, (SOCKADDR *)&m_dest, sizeof(m_dest));
    //if (iRet == SOCKET_ERROR)
    if (iRet <= 0)
    {
        //printf("Error sending Packet : %d",WSAGetLastError());
        int iError  =WSAGetLastError();
        MyMessageBox_Error(_T("RawSend"));
    }
}

void AFRawSocket::RawDisconnect()
{
    if (m_socket)
    {
        closesocket(m_socket);
        m_socket = NULL;
    }
}

很少有版本的Windows支持原始套接字,请检查first.thx,但我是Win7 ultimate的管理员,同时我成功发送了自建Ip头、UDP和ICMP,只有TCP失败,所以我们可以假设原始套接字受支持吗?据我所知,我可能错了,Windows开始在WinXp中支持原始套接字,并将其保留到WinXp SP2,WinPCAP等驱动程序仍然可以使用它,但我不确定在用户空间中是否可以。在调用sendto之前,通过硬代码重新创建结构,您是否可以加倍确保您的目的地在某个时候没有损坏?@hsluoyz您可能会提到