socket创建失败

寻常白昼 2016-04-17 08:46:38
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <time.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <iostream.h>
#pragma comment(lib,"ws2_32.lib")
typedef struct ip_hdr //定义IP首部
{
UCHAR h_verlen; //4位首部长度,4位IP版本号
UCHAR tos; //8位服务类型TOS
USHORT total_len; //16位总长度(字节)
USHORT ident; //16位标识
USHORT frag_and_flags; //3位标志位
UCHAR ttl; //8位生存时间 TTL
UCHAR proto; //8位协议 (TCP, UDP 或其他)
USHORT checksum; //16位IP首部校验和
ULONG sourceIP; //32位源IP地址
ULONG destIP; //32位目的IP地址
}IP_HEADER;

typedef struct tsd_hdr //定义TCP伪首部
{
ULONG saddr; //源地址
ULONG daddr; //目的地址
UCHAR mbz; //没用
UCHAR ptcl; //协议类型
USHORT tcpl; //TCP长度
}PSD_HEADER;

typedef struct tcp_hdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
ULONG th_seq; //32位序列号
ULONG th_ack; //32位确认号
UCHAR th_lenres; //4位首部长度/6位保留字
UCHAR th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
//以下是伪首部定义
ULONG saddr; //源地址
ULONG daddr; //目的地址
UCHAR mbz; //没用
UCHAR ptcl; //协议类型
USHORT tcpl; //TCP长度
}TCP_HEADER;

//CheckSum:计算校验和的子函数
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size)
{
cksum += *(UCHAR*)buffer;
}

cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}

int main(int argc, char* argv[])
{
WSADATA WSAData;
SOCKET sock;

IP_HEADER ip_hdr;
TCP_HEADER tcp_hdr;
// PSD_HEADER tcp_hdr;

char Sendto_Buff[40000]; //发送缓冲区 //发送缓冲区最大值
unsigned short check_Buff[40000]; //检验和缓冲区
const char tcp_send_data[]={"This is my homework of networt,I am happy!"};

BOOL flag;
int rect,nTimeOver;

if (argc!= 5)
{
printf("Useage: SendTcp soruce_ip source_port dest_ip dest_port \n");
return false;
}

if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
{
printf("WSAStartup Error!\n");
return false;
}
sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_TCP,NULL,0,WSA_FLAG_OVERLAPPED);
flag=true;
setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag));
nTimeOver=1000;
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver));
//填充IP首部
ip_hdr.h_verlen=(4<<4 | sizeof(ip_hdr)/sizeof(unsigned long));
ip_hdr.tos=(UCHAR)0;
ip_hdr.total_len=htons((unsigned short)sizeof(ip_hdr)+sizeof(tcp_hdr)+sizeof(tcp_send_data));
ip_hdr.ident=0; //16位标识
ip_hdr.frag_and_flags=0; //3位标志位
ip_hdr.ttl=128; //8位生存时间
ip_hdr.proto=IPPROTO_TCP; //协议类型
ip_hdr.checksum=0; //检验和暂时为0
ip_hdr.sourceIP=inet_addr(argv[1]); //32位源IP地址
ip_hdr.destIP=inet_addr(argv[3]); //32位目的IP地址

//计算IP头部检验和
memset(check_Buff,0,40000);
memcpy(check_Buff,&ip_hdr,sizeof(IP_HEADER));
ip_hdr.checksum=checksum(check_Buff,sizeof(IP_HEADER));

//构造TCP伪首部
tcp_hdr.saddr=ip_hdr.sourceIP;
tcp_hdr.daddr=ip_hdr.destIP;
tcp_hdr.mbz=0;
tcp_hdr.ptcl=ip_hdr.proto;
tcp_hdr.tcpl=htons(sizeof(TCP_HEADER)+sizeof(tcp_send_data));

//填充TCP首部
tcp_hdr.th_dport=htons(atoi(argv[4])); //16位目的端口号
tcp_hdr.th_sport=htons(atoi(argv[2])); //16位源端口号
tcp_hdr.th_seq=0; //SYN序列号
tcp_hdr.th_ack=0; //ACK序列号置为0
//TCP长度和保留位
tcp_hdr.th_lenres=(sizeof(tcp_hdr)/sizeof(unsigned long)<<4|0);
tcp_hdr.th_flag=2; //修改这里来实现不同的标志位探测,2是SYN,1是//FIN,16是ACK探测 等等
tcp_hdr.th_win=htons((unsigned short)16384); //窗口大小
tcp_hdr.th_urp=0; //偏移大小
tcp_hdr.th_sum=0; //检验和暂时填为0

//计算TCP校验和
memset(check_Buff,0,40000);
memcpy(check_Buff,&tcp_hdr,sizeof(tcp_hdr));
memcpy(check_Buff+sizeof(tcp_hdr),&tcp_hdr,sizeof(tcp_hdr));
memcpy(check_Buff+sizeof(PSD_HEADER)+sizeof(TCP_HEADER),
tcp_send_data,sizeof(tcp_send_data));
tcp_hdr.th_sum=checksum(check_Buff,sizeof(PSD_HEADER)+
sizeof(TCP_HEADER)+sizeof(tcp_send_data));

//填充发送缓冲区
memset(Sendto_Buff,0,40000);
memcpy(Sendto_Buff,&ip_hdr,sizeof(IP_HEADER));
memcpy(Sendto_Buff+sizeof(IP_HEADER),&tcp_hdr,
sizeof(TCP_HEADER));
memcpy(Sendto_Buff+sizeof(IP_HEADER)+sizeof(TCP_HEADER),
tcp_send_data,sizeof(tcp_send_data));
int datasize=sizeof(IP_HEADER)+sizeof(TCP_HEADER)+
sizeof(tcp_send_data);
//发送数据报的目的地址
SOCKADDR_IN dest;
memset(&dest,0,sizeof(dest));
dest.sin_family=AF_INET;
dest.sin_addr.s_addr=inet_addr(argv[3]);
dest.sin_port=htons(atoi(argv[4]));
rect=sendto(sock,Sendto_Buff,datasize, 0,(struct sockaddr*)&dest, sizeof(dest));
if (rect==SOCKET_ERROR)
{
printf("send error!:%d\n",WSAGetLastError());
return false;
}
else
printf("send ok!\n");
closesocket(sock);
WSACleanup();
return 1;
}

各位大神,这是发送TCP报文的程序,程序输入 SendTcp soruce_ip source_port dest_ip dest_port,我想问这里面socket创建失败报send error!:10038错误是怎么回事,要怎么修改使程序正确输出send OK!
...全文
274 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
kinkon007 2016-04-18
  • 打赏
  • 举报
回复
sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_TCP,NULL,0,WSA_FLAG_OVERLAPPED); flag=true; setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag)); nTimeOver=1000; setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver)); 这些代码都没有检查函数是否执行成功啊,10038一般是无效socket的,你看下创建的socket是否成功,raw socket一般也是要管理员的权限吧
寻常白昼 2016-04-18
  • 打赏
  • 举报
回复
也就是说我要以管理员身份登录系统,然后运行程序吗?第一次要以管理员权限运行代码的....

18,356

社区成员

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

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