最近在学习socket网络编程,网上找到一段代码。但运行时报10040错误,查询错误代码显示是缓存不够但我设置的数据缓存是很大的一个值,不可能是数据缓冲不够。有懂socket的朋友帮我看看代码哪里有问题,另外原代码是通过IP来ping 如果改成域名的话需要改哪里
#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
#pragma warning( disable : 4996)
//常量定义
const int MAX_ICMP_PACKET_SIZE = 204800; //ICMP报文最大长度(包括报头)
const int DEF_ICMP_DATA_SIZE = 131072; //ICMP报文默认数据字段长度
const int ICMP_ECHO_REQUEST = 8; //ICMP类型字段,8表示请求回显
//ICMP的报头格式
typedef struct SIcmpHdr
{
BYTE bType; //ICMP类型码
BYTE bCode; //子类型码
USHORT sCksum; //校验和
USHORT sId; //ICMP数据报的ID号
USHORT sSeq; //ICMP数据报的序列号
ULONG lTimeStamp; //可选数据部分
}
SICMPHDR, * LPSICMPHDR;
//IP报头格式
typedef struct SIpHdr
{
unsigned char cHdrLen; //4位头部长度
unsigned char cVersion; //4位版本号
unsigned char cTos; //8位服务类型
unsigned short sTotalLen; //16位总长度
unsigned short sIdentifier; //16位标示符
unsigned short sFragAndFlags; //3位标志加13位片偏移
unsigned char cTTL; //8位生存时间
unsigned char cProtocol; //8位上层协议号
unsigned short sCheckSum; //16位校验和
unsigned long lSrcIp; //32位源IP地址
unsigned long lDstIp; //32位目的IP地址
}
SIPHDR, * LPSIPHDR;
//计算校验和函数
USHORT CheckSum(USHORT* pBuf, int iSize)
{
unsigned long cksum = 0;
while (iSize > 1) {
cksum += *pBuf++;
iSize -= sizeof(USHORT);
}
if (iSize)
cksum += *(UCHAR*)pBuf;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
}
void Ping(char* lpszHostAddr)
{
//初始化
WSADATA stWSA; WSAStartup(MAKEWORD(2, 2), &stWSA);
SOCKET hRawSock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);//创建原始套接字
if (hRawSock == INVALID_SOCKET) {
printf("创建原始套接字失败(ErrorCode : %d)\n", WSAGetLastError());
system("PAUSE");
return;
}
//设置socket的超时机制
int iTimeout = 1000;//设置延时为1秒
int iRet = setsockopt(hRawSock, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimeout, sizeof(iTimeout));
if (iRet == SOCKET_ERROR) {
printf("设置延时失败(ErrorCode : %d)\n", WSAGetLastError());
system("PAUSE");
return;
}
//填充数据报
char szBuff[MAX_ICMP_PACKET_SIZE];
memset(szBuff, 0, MAX_ICMP_PACKET_SIZE);
int iDatSize = DEF_ICMP_DATA_SIZE;
iDatSize += sizeof(SICMPHDR);
((LPSICMPHDR)szBuff)->bType = ICMP_ECHO_REQUEST;//设置类型信息
((LPSICMPHDR)szBuff)->sId = (USHORT)GetCurrentThreadId();//设置ID号为当前线程号
memset(szBuff + sizeof(SICMPHDR), 'E', iDatSize - sizeof(SICMPHDR));//在ICMP数据部分填入数据
((LPSICMPHDR)szBuff)->sCksum = 0;
((LPSICMPHDR)szBuff)->lTimeStamp = GetTickCount();
((LPSICMPHDR)szBuff)->sSeq = 0;
((LPSICMPHDR)szBuff)->sCksum = CheckSum((USHORT*)szBuff, iDatSize);
//发送数据报文
sockaddr_in saDst; saDst.sin_family = AF_INET; saDst.sin_addr.s_addr = inet_addr(lpszHostAddr);
int iSend = sendto(hRawSock, szBuff, iDatSize, 0, (struct sockaddr*)&saDst, sizeof(saDst));
if (iSend == SOCKET_ERROR || iSend < iDatSize) {
printf("发送失败(ErrorCode : %d)\n", WSAGetLastError());
system("PAUSE");
return;
}
//接收回应报文
sockaddr_in saFrom;
int iSaLen = sizeof(saFrom);
memset(szBuff, 0, MAX_ICMP_PACKET_SIZE);
int iRecv = recvfrom(hRawSock, szBuff, MAX_ICMP_PACKET_SIZE, 0, (struct sockaddr*)&saFrom, &iSaLen);
if (iRecv <= 0) {
printf("接收回应报文失败(ErrorCode : %d)\n", WSAGetLastError());
system("PAUSE");
return;
}
LPSIPHDR lpIp = (LPSIPHDR)szBuff;
unsigned short iIpHdr = lpIp->cHdrLen * 4;//IP报头的长度
LPSICMPHDR lpIcmp = (LPSICMPHDR)(szBuff + iIpHdr);
//判断是否是目的端发回的消息
if (lpIcmp->sId == (USHORT)GetCurrentThreadId()) return;
printf("Ping %s successfully !\n", inet_ntoa(saFrom.sin_addr));
closesocket(hRawSock);//关闭套接字
system("PAUSE");
return;
}
void main()
{
Ping((char*)("192.168.0.1"));
}
先把 DEF_ICMP_DATA_SIZE 设置成500 , 先发少一点看下是否有问题,如果没有问题说明应该太大引起的问题。 还有上面说缓冲区设置了很大,有没有设置成功?get一下看看sendbuf大小
遇到错误要调试啊,
你这里又有定义,又有发送,又有接收,你好歹先确定到底是哪一步报错,再找原因
不要靠猜
先把printf打印错误信息都换成perror,这样缩小范围了再找错