实验一:unsigned short checkSum(char*pBuffer,int nLen){unsigned short nWord;unsigned int nSum=0;int i;for(i=0;i<nLen;i=i+2){nWord=((pBuffer[i]<<8)&0xFF00)+(pBuffer[i+1]&0xFF);nSum=nSum+(unsigned int)nWord;}while(nSum>>16){nSum=(nSum&0xFFFF)+(nSum>>16);}nSum=~nSum;return((unsigned short)nSum);}int timeout=1000;setsockopt(sock_raw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));setsockopt(sock_raw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout)); ICMPheader*pIcmpHeader=(ICMPheader*)sendBuffer;pIcmpHeader->byType=8;pIcmpHeader->byCode=0;pIcmpHeader->nId=(USHORT)::GetCurrentProcessId();pIcmpHeader->nChecksum=0;pIcmpHeader->nSequence=htons(nSeq++);memset(sendBuffer+sizeof(ICMPheader),'*',32);pIcmpHeader->nChecksum=htons(checkSum(sendBuffer,sizeof(ICMPheader)+32));int nRet=sendto(sock_raw,sendBuffer,sizeof(ICMPheader)+32,0, (SOCKADDR*)&dest_addr,sizeof(SOCKADDR_IN));IPheader*ipHdr=(IPheader*)recvBuffer;ICMPheader*icmpHdrRet=(ICMPheader*)(recvBuffer+sizeof(IPheader));if(icmpHdrRet->byCode==0&&icmpHdrRet->nId==pIcmpHeader->nId&&icmpHdrRet->nSequence==pIcmpHeader->nSequence){nPacketReceived++;unsigned long dwRecvTime=::GetTickCount();int nRoundTime=dwRecvTime-dwSendTime;nTotalRoundTime+=nRoundTime;if(nMinRoundTime==-1){nMinRoundTime=nRoundTime;nMaxRoundTime=nRoundTime;}if(nRoundTime<nMinRoundTime){nMinRoundTime=nRoundTime;}if(nRoundTime>nMaxRoundTime){nMaxRoundTime=nRoundTime;}cout<<"Reply from "<<inet_ntoa(from_addr.sin_addr)<<": bytes = "<<nRet-sizeof(ICMPheader)-sizeof(IPheader)<<", time = "<<nRoundTime<<"ms, TTL = "<<(int)ipHdr->byTtl<<endl;}unsigned long dwSendTime=::GetTickCount();cout<<endl<<"Ping statistics for "<<inet_ntoa(from_addr.sin_addr)<<":"<<endl <<"\t"<<"Packets:sent = "<<nPacketSent<<", Received = "<<nPacketReceived<<", Lost = "<<(nPacketSent-nPacketReceived)<< "("<<((float)(nPacketSent-nPacketReceived)/nPacketSent)*100<<"% loss)"<< endl;if(nPacketReceived){cout<<"\rApproximate round trip times in milli-seconds:"<<endl<<'\t' <<"Minimum = "<<nMinRoundTime<<"ms, Maximum = "<<nMaxRoundTime<<"ms, Average = "<<(float)nTotalRoundTime/nPacketReceived<<"ms"<<endl;}实验二://此函数获取本机DNS服务器地址(为点分十进制计法的字符串形式),并保存到dnsServer中,这里需要Iphlpapi.h和IPHLPAPI.LIBvoid getDnsServer(char*dnsServer){//获得需要的缓冲区大小DWORD nLength=0;if(GetNetworkParams(NULL,&nLength)!=ERROR_BUFFER_OVERFLOW){return;}FIXED_INFO*pFixedInfo=(FIXED_INFO*)new BYTE[nLength];//获得本地计算机网络参数if(GetNetworkParams(pFixedInfo,&nLength)!=ERROR_SUCCESS){delete[]pFixedInfo;return;}IP_ADDR_STRING*pCurrentDnsServer=&pFixedInfo->DnsServerList;if(pCurrentDnsServer!=NULL){char*tmp=pCurrentDnsServer->IpAddress.String;//pCurrentDnsServer->IpAddress.String即为我们所需要的字符串形式的DNS服务器IP地址strcpy(dnsServer,tmp);}}//对域名字符串进行解析并进行形式的变换,例如将"\0"变成"3www4wust3edu2cn0x00"char*pTrace=hostname;char*pHostname=hostname;int iStrLen=strlen(hostname);unsigned char iCharNum=0;while(*pTrace!='\0')//指针移到最后并从最后一个字符'\0'开始,每个字符往后移一个字节{pTrace++;}while(pTrace!=hostname){*(pTrace+1)=*pTrace;pTrace--;}*(pTrace+1)=*pTrace;//把第一个字符移到第二个字符位置pTrace++;//此时第一个字符没有实际意义,将指针指向原字符串中第二个字符的位置while(*pTrace!='\0')//从第一个字符开始扫描,iCharNum统计每两个字符'.'之间的字符数,然后填入原来字符'.'的位置{if(*pTrace=='.'){*pHostname=iCharNum;iCharNum=0;pHostname=pTrace;}else{iCharNum++;}pTrace++;}*pHostname=iCharNum;//最后一个字符'.'之后的字符数写入,例如"3www6google3com.hk"中的".hk"for(int i=1;i<=iRespNum;i++){pTraceResponse+=sizeof(short);//指针跳过应答记录的“域名”字段,此“域名”字段一般为一个域名指针,以0xC0开始。
pResponse=(pRESPONSE)pTraceResponse;if(ntohs(pResponse->type)==1)//这条应答记录返回的是与之前查询所对应的IP地址{pTraceResponse+=sizeof(RESPONSE);unsigned long ulIP=*(unsigned long*)pTraceResponse;address.s_addr=ulIP;//获取IP地址信息保存到ulIP,并写入address 里面if(i==iRespNum)//最后一条记录显示句号,否则显示分号{printf("%s. ",inet_ntoa(address));}else{printf("%s; ",inet_ntoa(address));}pTraceResponse+=sizeof(long);//指针移过应答记录的IP地址字段,指向下一个应答记录}else if(ntohs(pResponse->type)==5)//这条应答记录为所查询主机的一个别名,这里本程序直接跳过这条记录{pTraceResponse+=sizeof(RESPONSE);pTraceResponse+=ntohs(pResponse->length);}}实验三:if((g_events[0]=WSACreateEvent())==WSA_INVALID_EVENT){printf("错误:WSACreateEvent failed with error %d\n",WSAGetLastError());return;}//操作临界区,防止出错EnterCriticalSection(&g_cs);//创建一个新的SOCKET_INF结构处理接受的数据socket.if((g_sockets[g_dwEventTotal]=(LPSOCKET_INF)GlobalAlloc(GPTR,sizeof(SOCKET_INF)))==NULL){printf("错误:GlobalAlloc() failed with error %d\n",GetLastError());return;}//初始化新的SOCKET_INF结构char buff[DATA_BUFSIZE];memset(buff,0,DATA_BUFSIZE);g_sockets[g_dwEventTotal]->wsaBuf.buf=buff;g_sockets[g_dwEventTotal]->wsaBuf.len=DATA_BUFSIZE;g_sockets[g_dwEventTotal]->s=sAccept;memset(&(g_sockets[g_dwEventTotal]->o),0,sizeof(OVERLAPPED));g_sockets[g_dwEventTotal]->dwBytesSend=0;g_sockets[g_dwEventTotal]->dwBytesRecv=0;g_sockets[g_dwEventTotal]->nStatus=WSA_RECV;// 接收//创建事件if((g_sockets[g_dwEventTotal]->o.hEvent=g_events[g_dwEventTotal]= WSACreateEvent())==WSA_INVALID_EVENT){printf("WSACreateEvent() failed with error %d\n",WSAGetLastError());return;}//发出接受请求dwFlags=0;if(WSARecv(g_sockets[g_dwEventTotal]->s,&(g_sockets[g_dwEventTotal]->wsaBuf),1,&dwRecvBytes,&dwFlags,&(g_sockets[g_dwEventTotal]->o),NULL)==SOCKET_ERROR){if(WSAGetLastError()!=ERROR_IO_PENDING){printf("错误:WSARecv() failed with error %d\n",WSAGetLastError());return;}}g_dwEventTotal++;//离开临界区LeaveCriticalSection(&g_cs);if(strstr(szCmd,"PORT")){if(ConvertDotAddress(pSI->buffRecv+strlen("PORT")+1,&dwIpAddr,&wPort)== -1)return-1;const char*szPortCmdOK="200 PORT Command successful.\r\n";sprintf(pSI->buffSend,"%s",szPortCmdOK);if(SendRes(pSI)==-1)return-1;bPasv=FALSE;return CMD_OK;}if(strstr(szCmd,"PASV")){if(DataConn(s,htonl(INADDR_ANY),PORT_BIND,MODE_PASV)==-1) return-1;char*szCommaAddress=ConvertCommaAddress(GetLocalAddress(),PORT_BIND);sprintf(pSI->buffSend,"227 Entering Passive Mode(%s).\r\n",szCommaAddress);if(SendRes(pSI)==-1)return-1;bPasv=TRUE;return PASSIVE_MODE;}int ConvertDotAddress(char*szAddress,LPDWORD pdwIpAddr,LPWORD pwPort) {int idx=0,i=0,iCount=0;char szIpAddr[MAX_ADDR_LEN];memset(szIpAddr,0,sizeof(szIpAddr));char szPort[MAX_ADDR_LEN];memset(szPort,0,sizeof(szPort));*pdwIpAddr=0;*pwPort=0;while(szAddress[idx]){if(szAddress[idx]==','){iCount++;szAddress[idx]='.';}if(iCount<4)szIpAddr[idx]=szAddress[idx];elseszPort[i++]=szAddress[idx];idx++;}if(iCount!=5)return-1;*pdwIpAddr=inet_addr(szIpAddr);if(*pdwIpAddr==INADDR_NONE)return-1;char*pToken=strtok(szPort+1,".");if(pToken==NULL)return-1;*pwPort=(WORD)(atoi(pToken)*256);pToken=strtok(NULL,".");if(pToken==NULL)return-1;*pwPort+=(WORD)atoi(pToken);return0;}char*ConvertCommaAddress(char*szAddress,WORD wPort){char szPort[10];sprintf(szPort,"%d,%d",wPort/256,wPort%256);char szIpAddr[20];sprintf(szIpAddr,"%s,",szAddress);int idx=0;while(szIpAddr[idx]){if(szIpAddr[idx]=='.')szIpAddr[idx]=',';idx++;}sprintf(szAddress,"%s%s",szIpAddr,szPort);return szAddress;}。