如何获的关于ip,icmp等在winsock中的结构定义

oddstar 2000-03-10 09:44:00
我想在socket函数中用RAW参数,可我不知道ip,icmp,arp等的结构定义
...全文
234 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
王释之 2000-03-16
  • 打赏
  • 举报
回复
可以给我一份吗?谢谢! befresh@263.net
shuke 2000-03-12
  • 打赏
  • 举报
回复
struct arp {
short ar_hwtype; /* hardware type */
short ar_prtype; /* protocol type */
char ar_hwlen; /* hardware address length */
char ar_prlen; /* protocol address length */
short ar_op; /* ARP operation (see list above) */
char ar_addrs[1];/* sender and target hw & proto addrs */
/* char ar_sha[???]; /* sender's physical hardware address */
/* char ar_spa[???]; /* sender's protocol address (IP addr.) */
/* char ar_tha[???]; /* target's physical hardware address */
/* char ar_tpa[???]; /* target's protocol address (IP) */
};



struct ip {
char ip_verlen; /* IP version & header length (in longs)*/
char ip_tos; /* type of service */
short ip_len; /* total packet length (in octets) */
short ip_id; /* datagram id */
short ip_fragoff; /* fragment offset (in 8-octet's) */
char ip_ttl; /* time to live, in gateway hops */
char ip_proto; /* IP protocol (see IPT_* above) */
short ip_cksum; /* header checksum */
IPaddr ip_src; /* IP address of source */
IPaddr ip_dst; /* IP address of destination */
char ip_data[1]; /* variable length data */
};


struct icmp { /* ICMP packet */
char ic_type; /* type of message (ICT_* above)*/
char ic_code; /* code (ICC_* above) */
short ic_cksum; /* checksum of ICMP header+data */

union {
struct {
short ic1_id; /* for echo type, a message id */
short ic1_seq;/* for echo type, a seq. number */
} ic1;
IPaddr ic2_gw; /* for redirect, gateway */
struct {
char ic3_ptr;/* pointer, for ICT_PARAMP */
char ic3_pad[IC_PADLEN];
} ic3;
int ic4_mbz; /* must be zero */
} icu;
char ic_data[1]; /* data area of ICMP message */
};

RealTop 2000-03-11
  • 打赏
  • 举报
回复
icmp包结构
用C语言大致描述为:
typedef struct _tag_ICMP
{
BYTE PacketType;
WORD CheckSum;
WORD Identifier;
WORD SequenceNumber;
BYTE Data[];
}ICMP_PACKET;
如果需要我帮忙,MailTo:RealTop@21cn.com
oddstar 2000-03-10
  • 打赏
  • 举报
回复
king请发到oddstar@sohu.com
King 2000-03-10
  • 打赏
  • 举报
回复
我翻译了一篇ICMP数据包结构,要不要寄给你?要原文也可以,不过是E文
我们知道,TCP/IP网络数据全部是通过封装在IP数据包在Internet网上传送的,也就是封装建立起一个包含IP头和数据的IP数据报。一般来说,网络软件总是以多个32位字产生IP头,即使必须用附加的0填充IP头。IP头包含了传输IP数据包封装数据的所有必要信息。IP头的数据结构和描述如下: 成员 长度(Bit) 描述 Version 4 IP头的版本号,目前是IPv4,最新是IPv6 Header Length 4 IP头的长度,若没有特殊选择,IP头总是20字节长 Type of Service 8 服务类型,定义了数据传输的优先级、延迟、吞吐量和可靠性等特性 Total Packet Length 16 IP包的长度,若没有特殊选项,一般为20字节长 Identification 16 IP包标识,主机使用它唯一确定每个发送的数据报 Flag 3 IP数据分割标志 Fragment Offset 13 IP数据分割偏移 Time to Live 8 数据报在网络上的存活时间,每通过一个路由器,该数值减一 Protocol 8 TCP/IP协议类型,比如:ICMP为1,IGMP为2,TCP为6,UDP为17等 Header Checksum 16 头部检验和 Source IP Address 32 源IP地址 Destination IP Address 32 目的IP地址 Other ? 其他选项 Data ? 数据    实现自己定义IP头是一件非常有意义的事情,比如,通过改变IP头里的TOS的优先级和TTL,你可以使自己的数据包有更强的传输能力和寿命,通过修改IP头里的源IP地址就可以隐藏自己机器的IP地址等等。象著名攻击程序“泪滴TearDrop”就是通过故意制造系统不能处理的分片IP包而实现的,还有SYN Flooder和UDP Flooder就是通过产生随机源IP实现欺骗的。 三、实现原理    一般来说,自定义IP头是通过使用socket的库函数setsockopt()的选项IP_HDRINCL来实现的,尽管这在unix和linux平台上很容易实现,但遗憾的是在Windows平台的Winsock1.1和Winsock2.0函数库里setsockopt()不支持IP_HDRINCL选项,所以在Windows 9x/NT里是无法通过Winsock函数库来实现IP头自定义的,当然可以通过编写虚拟设备驱动程序来实现,不过比较复杂,但Windows 2000的出现打破了这种局面,Windows2000的Winsock2.2函数库里全面支持setsockopt()的选项IP_HDRINCL,使得我们轻松就可以实现自定义IP头。实现方法如下: SOCKET s; BOOL bopt; s=WSASocket(AF_INET, SOCK_RAW, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED); ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)bopt, sizeof(bopt); 四、实例   为帮助大家尽快地学会构造自己的IP头数据,特给出一个完整的实例,例子的功能是:只要给出对方的IP地址,就可以发送给对方的OICQ一个“hello!”消息,并且由于修改了发送数据包的IP头,完全实现了发送方IP地址的隐藏,也就是说稍加修改你就可以制作出一个能够完完全全的匿名OICQ发送器,当然,若是故意捣乱的话,后果自负。源代码如下: /***********************************************************************/ /* OicqSend.c                                            */ /* 本程序用Visual C++ 6.0编译在Windows 2000 Advanced Server 上调试通过 */ /* Created by janker@371.net 2000.8.28                         */ /* 声明:本程序经修改后可能会产生攻击性擅自修改成攻击程序者后果自负  */ /***********************************************************************/ #pragma pack(1) #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #define OICQ_MAX_PACKET 1024 #define OICQ_MAX_MSG 512 #define OICQ_MSG_LEN 45 #define SRC_IP "127.0.0.1" #define SRC_PORT 5277 #define DST_PORT 4000 typedef struct ip_hdr { unsigned char ip_verlen; unsigned char ip_tos; unsigned short ip_totallength; unsigned short ip_id; unsigned short ip_offset; unsigned char ip_ttl; unsigned char ip_protocol; unsigned short ip_checksum; unsigned int ip_srcaddr; unsigned int ip_destaddr; } IP_HDR; typedef struct udp_hdr { unsigned short src_portno; unsigned short dst_portno; unsigned short udp_length; unsigned short udp_checksum; } UDP_HDR; char strMessage[OICQ_MSG_LEN] = { 0x02,0x01,0x07,0x00,0x78,0x00,0x00,0x31,0x30,0x30,0x30,0x31,0x1f,0x30,0x1f, 0x30,0x30,0x1f,0x32,0x30,0x30,0x30,0x2d,0x30,0x31,0x2d,0x30,0x31,0x1f,0x30, 0x30,0x3a,0x30,0x30,0x3a,0x30,0x30,0x1f,0x68,0x65,0x6c,0x6c,0x6f,0x21,0x03 }; 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 wsd; SOCKET s; BOOL bOpt; struct sockaddr_in remote; IP_HDR ipHdr; UDP_HDR udpHdr; int ret; DWORD i; unsigned short iTotalSize, iUdpSize, iUdpChecksumSize, iIPVersion, iIPSize, cksum = 0; char buf[OICQ_MAX_PACKET], *ptr = NULL; printf("Spoof OICQ Msg Sender - by Janker@371.net\n\n"); if(argc!=2) { printf("usage: OICQSEND Destination_IP_Address"); ExitProcess(1); } srand((unsigned)time(NULL)); strMessage[5]=rand(); if (WSAStartup(MAKEWORD(2,2), &wsd;) != 0) { printf("WSAStartup() failed: %d\n", GetLastError()); return -1; } s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_UDP, NULL, 0,0); if (s == INVALID_SOCKET) { printf("WSASocket() failed: %d\n", WSAGetLastError()); return -1; } bOpt = TRUE; ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt;, sizeof(bOpt)); if (ret == SOCKET_ERROR) { printf("setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError()); return -1; } iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + OICQ_MSG_LEN; iIPVersion = 4; iIPSize = sizeof(ipHdr) / sizeof(unsigned long); ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize; ipHdr.ip_tos = 0; ipHdr.ip_totallength = htons(iTotalSize); ipHdr.ip_id = 0; ipHdr.ip_offset = 0; ipHdr.ip_ttl = 128; ipHdr.ip_protocol = 0x11; ipHdr.ip_checksum = 0 ; ipHdr.ip_srcaddr = inet_addr(SRC_IP); ipHdr.ip_destaddr = inet_addr(argv[1]); iUdpSize = sizeof(udpHdr) + OICQ_MSG_LEN; udpHdr.src_portno = htons(SRC_PORT) ; udpHdr.dst_portno = htons(DST_PORT) ; udpHdr.udp_length = htons(iUdpSize) ; udpHdr.udp_checksum = 0 ; iUdpChecksumSize = 0; ptr = buf; ZeroMemory(buf, OICQ_MAX_PACKET); memcpy(ptr, &ipHdr;.ip_srcaddr, sizeof(ipHdr.ip_srcaddr)); ptr += sizeof(ipHdr.ip_srcaddr); iUdpChecksumSize += sizeof(ipHdr.ip_srcaddr); memcpy(ptr, &ipHdr;.ip_destaddr, sizeof(ipHdr.ip_destaddr)); ptr += sizeof(ipHdr.ip_destaddr); iUdpChecksumSize += sizeof(ipHdr.ip_destaddr); ptr++; iUdpChecksumSize += 1; memcpy(ptr, &ipHdr;.ip_protocol, sizeof(ipHdr.ip_protocol)); ptr += sizeof(ipHdr.ip_protocol); iUdpChecksumSize += sizeof(ipHdr.ip_protocol); memcpy(ptr, &udpHdr;.udp_length, sizeof(udpHdr.udp_length)); ptr += sizeof(udpHdr.udp_length); iUdpChecksumSize += sizeof(udpHdr.udp_length); memcpy(ptr, &udpHdr;, sizeof(udpHdr)); ptr += sizeof(udpHdr); iUdpChecksumSize += sizeof(udpHdr); for(i = 0; i *ptr = strMessage[i]; iUdpChecksumSize += OICQ_MSG_LEN; cksum = checksum((USHORT *)buf, iUdpChecksumSize); udpHdr.udp_checksum = cksum; ZeroMemory(buf, OICQ_MAX_PACKET); ptr = buf; memcpy(ptr, &ipHdr;, sizeof(ipHdr)); ptr += sizeof(ipHdr); memcpy(ptr, &udpHdr;, sizeof(udpHdr)); ptr += sizeof(udpHdr); memcpy(ptr, strMessage, OICQ_MSG_LEN); remote.sin_family = AF_INET; remote.sin_port = htons(DST_PORT); remote.sin_addr.s_addr = inet_addr(argv[1]); ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote;, sizeof(remote)); if (ret == SOCKET_ERROR) printf("sendto() failed: %d\n", WSAGetLastError()); else printf("Send O.K.!"); closesocket(s) ; WSACleanup() ; return 0; }
《计算机网络原理》实验指导书 目录 《计算机网络原理》实验指导书1 实验一 IP协议分析2 一、实验目的2 二、实验学时2 三、实验类型2 四、实验步骤2 实验二 TCP网络编程5 一、实验目的5 二、实验学时5 三、实验类型5 四、实验步骤5 实验一 IP协议分析 一、实验目的 1. 掌握IP数据报的报文格式 2. 掌握子网掩码和路由转发 二、实验学时 4学时 三、实验类型 验证型实验 四、实验步骤 实验分组进行,每组6人,采用网络结构二. 说明:主机A、C、D的默认网关是172.16.1.1;主机E、F的默认网关是172.16.0.1. 主机B启动静态路由服务〔方法:在命令行方式下,输入"staticroute_config"〕. 按照拓扑结构图连接网络,使用拓扑验证检查连接的正确性. 练习一:领略真实的ARP〔同一子网〕 1. 主机A、B、C、D、E、F在命令行下运行"arp -a"命令,察看ARP高速缓存表. [问题] ARP高速缓存表由哪几项组成? 2. 主机A、B、C、D启动协议分析器,打开捕窗口进行数据捕并设置过滤条件〔提取 ARP、ICMP〕. 3. 主机A、B、C、D在命令行下运行"arp -d"命令,清空ARP高速缓存. 4. 主机A ping 主机D〔172.16.1.4〕. 5. 主机A、B、C、D停止捕数据,并立即在命令行下运行"arp -a"命令察看ARP高速缓存. [问题] 结合协议分析器上采集到的ARP报文和ARP高速缓存表新增加的条目,简述ARP协议的 报文交互过程以与ARP高速缓存表的更新过程. 练习二:编辑并发送IP数据报 1. 主机A启动仿真编辑器,编辑一个IP数据报,其: MAC层: 目的MAC地址:主机B的MAC地址〔对应于172.16.1.1接口的MAC〕. 源MAC地址:主机A的MAC地址. 协议类型或数据长度:0800. IP层: 总长度:IP层长度. 生存时间:128. 源IP地址:主机A的IP地址〔172.16.1.2〕. 目的IP地址:主机E的IP地址〔172.16.0.2〕. 校验和:在其他所有字段填充完毕后计算并填充. [问题] IP在计算校验和时包括哪些内容? 2. 在主机B〔两块网卡分别打开两个捕窗口〕、E上启动协议分析器,设置过滤条件〔 提取IP协议〕,开始捕数据. 3. 主机A发送第1步编辑好的报文. 4. 主机B、E停止捕数据,在捕到的数据查找主机A所发送的数据报. [问题] 第1步主机A所编辑的报文,经过主机B到达主机E后,报文数据是否发生变化?若发 生变化,记录变化的字段,并简述发生变化的原因. 5. 将第2步主机A所编辑的报文的"生存时间"设置为1.重新计算校验和. 6. 主机B、E重新开始捕数据. 7. 主机A发送第5步编辑好的报文. 8. 主机B、E停止捕数据,在捕到的数据查找主机A所发送的数据报. [问题] 主机B、E是否能捕到主机A所发送的报文?简述产生这种现象的原因. 实验二TCP网络编程 一、实验目的 1. 了解基于MFC的TCP网络编程的方式 2. 学习使用MFC编写简单的TCP网络程序 二、实验学时 4学时 三、实验类型 设计型实验 四、实验步骤 该实验以两位同学为一组,一位同学开发服务器程序,一位同学开发客户端程序.使得 客户端与服务器之间能够实现信息交换. 一、Windows Socket和套接口的基本概念 网际协议IP>是一种用于互联网的网络协议,已广为人知.它可广泛用于大多数计算机操 作系统上,也可用于大多数局域网LAN<比如办公室小型网络>和广域网WAN<比如说互联网 >.从它的设计看来,它是一个无连接的协议,并不能保证数据投递万无一失.两个上层协议 依赖IP协议进行数据通信. 如果希望在Microsoft Windows下通过TCP和UDP协议建立网络应用程序,则需要使用Winsock套接口编程技术. 套接口,就是一个指向传输提供者的句柄.Win32,套接口不同于文件描述符,所以它 是一个独立的类型——SOCKET.Windows Sockets描述定义了一个Microsoft Windows的网络编程界面,它是从Unix Socket的基础上发展而来的,为Windows TCP/IP提供了一个BSD型的套接字规范,除与4.3BSD Unix Sockets完全兼容外,还包括一个扩充文件,通过一组附加的API实现Windows式<即事件驱 动>的编程风格;而Winsock则是在MicrosoftWindows进行网络应用程序设计的接口.W indows在Internet支配域的TCP/IP协议定义Winsock网络编程规范,
第1章 计算机网络体系结构 1 1.1 网络术语及其拓扑结构 1 1.1.1 服务器、客户机和节点 1 1.1.2 本地资源和远程资源 1 1.1.3 网络操作系统 2 1.1.4 网络协议 2 1.1.5 网卡、桥和路由器 2 1.1.6 Intranet 3 1.1.7 拓扑结构 3 1.2 开放系统互连参考模型 3 1.2.1 物理层 4 1.2.2 数据链路层 4 1.2.3 网络层 5 1.2.4 传输层 5 1.2.5 会话层 5 1.2.6 表示层 6 1.2.7 应用层 6 1.2.8 OSI模型综述 6 1.3 TCP/IP参考模型 8 1.3.1 网络接口层 8 1.3.2 网际层 9 1.3.3 传输层 9 1.3.4 应用层 10 1.4 网络接口层及其相关协议 10 1.4.1 面向字符的链路层协议和面向比特的链路层协议 10 1.4.2 高级数据链路控制规程HDLC 11 1.4.3 X.25的链路层协议LAPB 13 1.4.4 点到点协议(PPP) 13 1.5 网际层及其相关协议 14 1.5.1 IP 14 1.5.2 消息控制协议 18 1.5.3 地址解析/反向地址解析协议 20 1.6 传输层及其相关协议 21 1.6.1 面向连接的TCP 21 1.6.2 无连接UDP 22 1.7 应用层及其相关协议 22 1.8 Intranet网络系统 23 1.8.1 Intranet网络组成 23 1.8.2 Intranet硬件结构 24 1.8.3 Intranet软件结构 25 1.9 小结 26 第2章 NetBIOS编程 27 2.1 Microsoft NetBIOS 27 2.1.1 LANA编号 28 2.1.2 NetBIOS名字 28 2.1.3 NetBIOS特性 31 2.2 NetBIOS基础 31 2.3 NetBIOS例程 33 2.3.1 异步回调模型 39 2.3.2 异步事件模型 43 2.3.3 NetBIOS会话客户端 47 2.4 其他NetBIOS命令 50 2.4.1 适配器状态 51 2.4.2 查找名字 52 2.4.3 对应传送协议同LANA编号 53 2.5 搜索指定网段内计算机 53 2.6 小结 58 第3章 重定向器、邮槽和管道 59 3.1 重定向器 59 3.1.1 命名规范 59 3.1.2 网络提供者 61 3.1.3 重定向器简介 61 3.1.4 服务器消息块 62 3.1.5 安全问题 62 3.1.6 网络安全 64 3.1.7 实例 64 3.2 邮槽 65 3.2.1 邮槽简介 66 3.2.2 基本客户端/服务器 68 3.2.3 其他邮槽API 74 3.3 管道 74 3.3.1 匿名管道 75 3.3.2 命名管道 77 3.3.3 客户端与服务器基础 83 3.3.4 其他API 97 3.3.5 命名管道通信 99 3.4 小结 103 第4章 网络协议TCP/IP 105 4.1 协议特征 105 4.1.1 面向消息 105 4.1.2 面向连接和无连接 106 4.1.3 可靠性和次序性 106 4.1.4 从容关闭 107 4.1.5 广播数据 107 4.1.6 多播数据 107 4.1.7 服务质量 107 4.1.8 部分消息 108 4.1.9 路由选择的考虑 108 4.1.10 其他特征 108 4.2 支持的协议 108 4.2.1 支持的Win32网络协议 109 4.2.2 Windows CE网络协议 110 4.3 网际协议(IP) 110 4.3.1 IP主要特征 110 4.3.2 IP数据报格式 111 4.3.3 IP服务定义和原语 116 4.3.4 IPv6 118 4.4 传输层协议TCP和UDP 123 4.4.1 传输层连接和端口地址 124 4.4.2 用户数据报协议(UDP) 127 4.4.3 传输控制协议TCP 129 4.4.4 定址 137 4.4.5 创建套接字 139 4.4.6 名字解析 139 4.4.7 端口号 140 4.5 TCP/IP安全性分析 141 4.5.1 TCP/IP整体构架安全分析 141 4.5.2 安全性和提高安全性方法 142 4.6 Winsock 2协议信息 145 4.7 具体平台的问题 147 4.8 综合实例 148 4.8.1 枚举系统支持网络协议 148 4.8.2 选择网络协议 156 4.8.3 TCP/IP信息统计 160 4.8.4 IP包监视 171 4.9 小结 178 第5章 局域网编程 179 5.1 局域网概述 179 5.1.1 局域网简史 179 5.1.2 局域网特点 180 5.1.3 局域网组成 180 5.2 网络接口卡与硬件编址 180 5.2.1 网卡基本结构 180 5.2.2 网卡参数 181 5.2.3 硬件编址与包过滤 182 5.2.4 硬件编址方式 183 5.2.5 广播与组播 184 5.2.6 帧格式 184 5.2.7 隐式帧网络 185 5.3 局域网拓扑结构 186 5.3.1 星型拓扑结构 186 5.3.2 环形拓扑结构 186 5.3.3 总线拓扑结构 187 5.3.4 树型结构 188 5.3.5 点对点连接 188 5.3.6 网状结构 188 5.4 局域网体系结构 189 5.4.1 IEEE 802局域网参考模型 189 5.4.2 IEEE 802局域网标准 191 5.4.3 以太网技术 192 5.4.4 令牌环网 196 5.5 综合实例 198 5.5.1 取网卡信息1 198 5.5.2 取网卡信息2 201 5.5.3 取网卡信息3 203 5.6 小结 211 第6章 Winsock基础 212 6.1 套接字 212 6.2 Socket编程模型与Winsock规范 214 6.2.1 Socket编程模型演化 215 6.2.2 Winsock套接字主要特点 216 6.3 初始化Winsock 217 6.4 建立Windows套接字 218 6.5 错误检查和控制 220 6.6 面向连接的协议 221 6.6.1 服务器API函数 221 6.6.2 客户端API函数 225 6.6.3 数据传输 228 6.6.4 流协议 231 6.6.5 断连接 233 6.6.6 综合分析 233 6.6.7 有连接通信示例 241 6.7 无连接协议 243 6.7.1 bind 243 6.7.2 创建服务器套接字 246 6.7.3 接收端 246 6.7.4 发送端 247 6.7.5 基于消息的协议 248 6.7.6 释放套接字资源 249 6.7.7 综合分析 249 6.7.8 无连接通信 255 6.8 其他API函数 258 6.9 小结 260 第7章 Winsock API高级编程 261 7.1 Winsock 输入/输出 261 7.1.1 套接字模式 261 7.1.2 I/O模型 264 7.2 套接字选项 302 7.2.1 SOL_SOCKET选项 303 7.2.2 IPPROTO_IP选项 308 7.2.3 IPPROTO_TCP选项 311 7.2.4 NSPROTO_IPX选项 311 7.3 套接字输出/输出控制 314 7.3.1 标准I/O控制 315 7.3.2 其他I/O控制 315 7.3.3 安全套接字层的I/O控制 320 7.4 原始套接字与底层传输协议 321 7.4.1 创建原始套接字 322 7.4.2 ICMP的实现 323 7.4.3 Internet组管理协议 336 7.4.4 IP_HDRINCL的使用 338 7.5 综合实例 345 7.5.1 枚举TCP和UDP连接状态 345 7.5.2 Ping实例 351 7.6 小结 357 第8章 MFC Winsock高级编程 359 8.1 Web基础知识 359 8.1.1 客户端 359 8.1.2 服务器 360 8.1.3 HTTP 362 8.2 HTTP服务器设计 363 8.2.1 同步操作 364 8.2.2 错误异常处理 364 8.2.3 发送/接收超时处理 364 8.3 创建自己的Winsock类 365 8.3.1 CSockAddress辅助类 365 8.3.2 CMyBlockSocketException类 367 8.3.3 CMyBlockSocket类 368 8.3.4 CMyHttpBlockSocket类 373 8.4 HTTP服务器示例 375 8.5 小结 386 第9章 深入UDP 387 9.1 局域网广播 387 9.1.1 广播通信的优缺点 387 9.1.2 广播通信实现 387 9.2 多播通信 389 9.2.1 多播的含义 389 9.2.2 IP多播 391 9.2.3 多播与Winsock 393 9.2.4 IP多播实例 407 9.3 多媒体通信与常规服务质量 412 9.3.1 背景知识 412 9.3.2 QOS和Winsock 416 9.3.3 QOS止 421 9.3.4 QOS编程 429 9.3.5 语音全双工通信 434 9.4 小结 450 第10章 WinInet API开发 451 10.1 WinInet与Winsock 451 10.2 使用WinInet API 452 10.2.1 句柄 452 10.2.2 错误处理 452 10.2.3 缓冲区参数 452 10.2.4 异步I/O 452 10.3 Internet函数 453 10.3.1 常用Internet函数 453 10.3.2 FTP客户端函数 459 10.3.3 HTTP客户端函数 461 10.3.4 Gopher客户端函数 465 10.4 WinInet API编程 465 10.4.1 HTTP客户编程 466 10.4.2 Cookies编程 468 10.4.3 FTP客户编程步骤 469 10.5 MFC WinInet类 472 10.5.1 WinInet类编程模型 473 10.5.2 其他常用函数 478 10.6 深入MFC WinInet类 482 10.6.1 CInternetSession类 483 10.6.2 连接类 483 10.6.3 文件类 484 10.6.4 CInternetException类 485 10.6.5 MFC WinInet类的关系 485 10.6.6 使用CInternetSession 486 10.6.7 FTP服务器处理 489 10.6.8 HTTP服务器处理 492 10.6.9 Gopher服务器处理 495 10.6.10 实现Internet查询 497 10.7 综合实例 505 10.7.1 多线程HTTP服务器 505 10.7.2 FTP客户端开发 529 10.8 小结 559 第11章 网络协议实现及应用 560 11.1 实现HTTP 560 11.1.1 HTTP 560 11.1.2 实现HTTP客户端 568 11.2 实现Telnet协议 572 11.2.1 Telnet协议 573 11.2.2 创建Telnet客户端 576 11.3 实现FTP 587 11.3.1 FTP 588 11.3.2 FTP应用程序 593 11.4 代理服务器 602 11.4.1 Socket 5协议 602 11.4.2 HTTP代理服务器 604 11.4.3 支持Socket5代理 615 11.5 信报API 622 11.5.1 MAPI结构 622 11.5.2 在MFC支持MAPI 624 11.5.3 通用信报调用 626 11.5.4 简单MAPI 633 11.5.5 扩展MAPI和OLE信报库 633 11.6 小结 633 第12章 综合实例 634 12.1 管道高级通信 634 12.2 电子邮件检查程序 647 12.3 文件下载 661 12.4 网络版五子棋游戏 675 12.5 小结 687
07网络工程本 制作人:北-624寝室 负责人:赖文斌 第四篇 网络编程 9. ping程序设计 ping命令是使用频率极高的一个网络测试命令,用以测试从一个主机到另一个主机 间的网络上否可达。windows自带的ping命令具有强大的功能,它有很多选项用于实现不 同的测试目的。本章模仿windows的ping命令,用c语言实现了一个简单的命令。本章着 重讲述ping命令的实现原理和c语言的网络编程方法。读者可以在本章的基础上,对本章 实现的ping命令进行扩展,开发出功能更强大、更完善的ping命令,并进一步掌握网络 编程的方法。 9.1 设计目的 本章通过设计Ping程序,讲解Ping程序的实现原理,并初步讲解了c语言网络编程技术。 本章涉及很多网络编程函数和编程技巧。包括库文件的导入;winsock的初始化、注销; socket的创建、关闭;设置socket选项;根据主机名IP地址; 从堆分配一定数量的空间、释放从堆分配的空间;取当前进程ID号;数据报的发 送;数据报的接等。 通过本程序的训练,使读者对网络编程有一定的了解,掌握Ping程序的设计方法,掌握 网络编程的方法和技巧,从而编写出功能更强大的程序。 9.2功能描述 本章用 c 语言实现的 ping命令,能用于测试一个主机到另一个主机间的联通情况,程序还提供了几个选项以 实现不同的功能。 (1)实现ping功能。程序能实现基本的ping操作,发送ICMP回显请求报文,接收显应答 报文。 (2)能记录路由。程序提供了"-r"选项,用以记录从源主机到目的主机的路由。 (3)能输出指定条数的记录。程序提供了"-n"选项,用以输出指定条数的记录。 (4)能按照指定大小输出每条记录。程序提供了"datasize"选项,用以指定输出的数据 报的大小。 (5)能输出用户帮助。程序提供了用户帮助,显示程序提供的选项以及选项格式等。 9.3 总体设计 9.3.1 功能模块设计 1. 功能模块图 本系统共有 4 个模块,分别是初始化模块、功能控制模块、数据控制模块、数据报解读模块和ping测 试模块,如图9.1所示。各模块功能描述如下。 图 9.1 系统模块图 (1) 初始化模块。改模块用于初始化各个全局变量,为全局变量赋初始值;初始化,加载库 。 (2)功能控制模块。改模块是被其它模块调用,其功能包括取参数、计算校验和填充数 据报文、释放占用资源和显示用户帮助。 (3)数据报解读模块。改模块用于解读接收到的报文和选项。 (4)测试模块。改模块是本程序的核心模块,调用其他模块实现其功能,主要是实现的功 能。 2.系统流程图 系统执行的流程图9.2所示。程序首先调用IniPing()函数初始化各全局变量,然后G etArgments()函数取用户输入的参数,检查用户输入的参数,如果参数不正确或者没 有输入参数,则显示用户帮助信息(User "(记录条数程序,任意的整数)和datasize(数据报大小)。程序首先判断每一个参数的 第一字符,如果第一个字符是"-"(短横线),则认为是"-r"或者"- n"的一个,然后作进一步判断。如果该参数的第二个字符是数字,则判断该参数为记 录的条数,如果该参数的第二个字符是"r",则判断该参数为"-r", 用于记录路由;如果参数的第一个字符是数字,则认为 参数是IP地址;或者datasize,然后作进一步的判断。如果该参数不存在非数字的字符 , 则判断该参数为datasize;如果存在非数 字的字符,则判断该参数为IP地址;其他情况则判断为主机名。参数取的流程如图9. 3所示。 图9.3 参数取流程图 4.ping()函数流程图 ping()函数是本程序的核心部分它调用其他模块的函数来实现,其主要步骤包括创建 接字,设置路由选项(如果需要的话)、设置接收和发送超时值、名字解析(如果需要 的话)、分配内存、创建ICMP报文、发送ICMP请求报文、接收ICMP应答报文和解读ICMP 报文。其执行流程如图9.4所示。 图9.4 Ping 函数流程图 9.3.2数据结构设计 本程序定义了3个结构体:-iphdr、-icmphdr、和- ipotionhdr,分别用于存放IP报头信息、ICM P报头信息和IP路由选项信息。 1. 定义IP报头结构体 Typedef struct _iphdr { Unsigned int :4; Unsigned int version:4; Unsigned char tos; Unsigned short total_len; Unsigned short ident; Unsigned short frag_flags; Unsigned char ttl; Unsigned chor proto;
1.static有什么用途?(请至少说明两种) 1)在函数体,一个被声明为静态的变量在这一函数被调用过程维持其值不变。 2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。 3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用 2.引用与指针有什么区别? 1) 引用必须被初始化,指针不必。 2) 引用初始化以后不能被改变,指针可以改变所指的对象。 3) 不存在指向空值的引用,但是存在指向空值的指针。 3.描述实时系统的基本特性 在特定时间内完成特定的任务,实时性与可靠性。 4.全局变量和局部变量在内存是否有区别?如果有,是什么区别? 全局变量储存在静态数据库,局部变量在堆栈。 5.什么是平衡二叉树? 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1。 6.堆栈溢出一般是由什么原因导致的? 没有回收垃圾资源。 7.什么函数不能声明为虚函数? constructor函数不能声明为虚函数。 8.冒泡排序算法的时间复杂度是什么? 时间复杂度是O(n^2)。 9.写出float x 与“零值”比较的if语句。 if(x>0.000001&&x<-0.000001) 10.Internet采用哪种网络协议?该协议的主要层次结构? Tcp/Ip协议 主要层次结构为: 应用层/传输层/网络层/数据链路层/物理层。 11.Internet物理地址和IP地址转换采用什么协议? ARP (Address Resolution Protocol)(地址解析協議) 12.IP地址的编码分为哪俩部分? IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。 13.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。 循环链表,用取余操作做 14.不能做switch()的参数类型是: switch的参数不能为实型。 1.写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式 a的值(3分) int a = 4; (A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++); a = ? 答:C错误,左侧不是一个有效变量,不能赋值,可改为(++a) += a; 改后答案依次为9,10,10,11 2.某32位系统下, C++程序,请计算sizeof 的值(5分). char str[] = “http://www.ibegroup.com/” char *p = str ; int n = 10; 请计算 sizeof (str ) = ?(1) sizeof ( p ) = ?(2) sizeof ( n ) = ?(3) void Foo ( char str[100]){ 请计算 sizeof( str ) = ?(4) } void *p = malloc( 100 ); 请计算 sizeof ( p ) = ?(5) 答:(1)17 (2)4 (3) 4 (4)4 (5)4 3. 回答下面的问题. (4分) (1).头文件的 ifndef/define/endif 干什么用?预处理 答:防止头文件被重复引用 (2). #i nclude 和 #i nclude “filename.h” 有什么区别? 答:前者用来包含开发环境提供的库头文件,后者用来包含自己编写的头文件。 (3).在C++ 程序调用被 C 编译器编译后的函数,为什么要加 extern “C”声明? 答:函数和变量被C++编译后在符号库的名字与C语言的不同,被extern "C"修饰的变 量和函数是按照C语言方式编译和连接的。由于编译后的名字不同,C++程序不能直接调 用C 函数。C++提供了一个C 连接交换指定符号extern“C”来解决这个问题。 (4). switch()不允许的数据类型是? 答:实型 4. 回答下面的问题(6分) (1).Void GetMemory(char **p, int num){ *p = (char *)malloc(num); } void Test(void){ char *str = NULL; GetMemory(&str, 100); strcpy(str, "hello"); printf(str); } 请问运行Test 函数会有什么样的结果? 答:输出“hello” (2). void Test(void){ char *str = (char *) malloc(100); strcpy(str, “hello”); free(str); if(str != NULL){ strcpy(str, “world”); printf(str); } } 请问运行Test 函数会有什么样的结果? 答:输出“world” (3). char *GetMemory(void){ char p[] = "hello world"; return p; } void Test(void){ char *str = NULL; str = GetMemory(); printf(str); } 请问运行Test 函数会有什么样的结果? 答:无效的指针,输出不确定 5. 编写strcat函数(6分) 已知strcat函数的原型是char *strcat (char *strDest, const char *strSrc); 其strDest 是目的字符串,strSrc 是源字符串。 (1)不调用C++/C 的字符串库函数,请编写函数 strcat 答: VC源码: char * __cdecl strcat (char * dst, const char * src) { char * cp = dst; while( *cp ) cp++; /* find end of dst */ while( *cp++ = *src++ ) ; /* Copy src to end of dst */ return( dst ); /* return dst */ } (2)strcat能把strSrc 的内容连接到strDest,为什么还要char * 类型的返回值? 答:方便赋值给其他变量 6.MFCCString是类型安全类么? 答:不是,其它数据类型转换到CString可以使用CString的成员函数Format来转换 7.C++为什么用模板类。 答:(1)可用来创建动态增长和减小的数据结构 (2)它是类型无关的,因此具有很高的可复用性。 (3)它在编译时而不是运行时检查数据类型,保证了类型安全 (4)它是平台无关的,可移植性 (5)可用于基本数据类型 8.CSingleLock是干什么的。 答:同步多个线程对一个数据类的同时访问 9.NEWTEXTMETRIC 是什么。 答:物理字体结构,用来设置字体的高宽大小 10.程序什么时候应该使用线程,什么时候单线程效率高。 答:1.耗时的操作使用线程,提高应用程序响应 2.并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。 3.多CPU系统,使用线程提高CPU利用率 4.改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独 立的运行部分,这样的程序会利于理解和修改。 其他情况都使用单线程。 11.Windows是内核级线程么。 答:见下一题 12.Linux有内核级线程么。 答:线程通常被定义为一个进程代码的不同执行路线。从实现方式上划分,线程有两 种类型:“用户级线程”和“内核级线程”。 用户线程指不需要内核支持而在用户程序 实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度 和管理线程的函数来控制用户线程。这种线程甚至在象 DOS 这样的操作系统也可实现 ,但线程的调度需要用户程序完成,这有些类似 Windows 3.x 的协作式多任务。另外一 种则需要内核的参与,由内核完成线程的调度。其依赖于操作系统核心,由内核的内部 需求进行创建和撤销,这两种模型各有其好处和缺点。用户线程不需要额外的内核开支 ,并且用户态线程的实现方式可以被定制或修改以适应特殊应用的要求,但是当一个线 程因 I/O 而处于等待状态时,整个进程就会被调度程序切换为等待状态,其他线程得不 到运行的机会;而内核线程则没有各个限制,有利于发挥多处理器的并发优势,但却占 用了更多的系统开支。 Windows NT和OS/2支持内核线程。Linux 支持内核级的多线程 13.C++什么数据分配在栈或堆,New分配数据是在近堆还是远堆? 答:栈: 存放局部变量,函数调用参数,函数返回值,函数返回地址。由系统管理 堆: 程序运行时动态申请,new 和 malloc申请的内存就在堆上 14.使用线程是如何防止出现大的波峰。 答:意思是如何防止同时产生大量的线程,方法是使用线程池,线程池具有可以同时提 高调度效率和限制资源使用的好处,线程池的线程达到最大数时,其他线程就会排队 等候。 15函数模板与类模板有什么区别? 答:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化 必须由程序员在程序显式地指定。 16一般数据库若出现日志满了,会出现什么情况,是否还能使用? 答:只能执行查询等读操作,不能执行更改,备份等写操作,原因是任何写操作都要记 录日志。也就是说基本上处于不能使用的状态。 17 SQL Server是否支持行级锁,有什么好处? 答:支持,设立封锁机制主要是为了对并发操作进行控制,对干扰进行封锁,保证数据 的一致性和准确性,行级封锁确保在用户取得被更新的行到该行进行更新这段时间内不 被其它用户所修改。因而行级锁即可保证数据的一致性又能提高数据操作的迸发性。 18如果数据库满了会出现什么情况,是否还能使用? 答:见16 19 关于内存对齐的问题以及sizof()的输出 答:编译器自动对齐的原因:为了提高程序的性能,数据结构(尤其是栈)应该尽可能 地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问 ;然而,对齐的内存访问仅需要一次访问。 20 int i=10, j=10, k=3; k*=i+j; k最后的值是? 答:60,此题考察优先级,实际写成: k*=(i+j);,赋值运算符优先级最低 21.对数据库的一张表进行操作,同时要对另一张表进行操作,如何实现? 答:将操作多个表的操作放入到事务进行处理 22.TCP/IP 建立连接的过程?(3-way shake) 答:在TCP/IP协议,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。   第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状 态,等待服务器确认; 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个 SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;   第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1) ,此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。 23.ICMP是什么协议,处于哪一层? 答:Internet控制报文协议,处于网络层(IP层) 24.触发器怎么工作的? 答:触发器主要是通过事件进行触发而被执行的,当对某一表进行诸如UPDATE、 INSERT 、 DELETE 这些操作时,数据库就会自动执行触发器所定义的SQL 语句,从而确保对数 据的处理必须符合由这些SQL 语句所定义的规则。 25.winsock建立连接的主要实现步骤? 答:服务器端:socker()建立套接字,绑定(bind)并监听(listen),用accept() 等待客户端连接。 客户端:socker()建立套接字,连接(connect)服务器,连接上后使用send()和recv( ),在套接字上写读数据,直至数据交换完毕,closesocket()关闭套接字。 服务器端:accept()发现有客户端连接,建立一个新的套接字,自身重新开始等待连 接。该新产生的套接字使用send()和recv()写读数据,直至数据交换完毕,closesock et()关闭套接字。 26.动态连接库的两种方式? 答:调用一个DLL的函数有两种方法: 1.载入时动态链接(load-time dynamic linking),模块非常明确调用某个导出函数 ,使得他们就像本地函数一样。这需要链接时链接那些函数所在DLL的导入库,导入库向 系统提供了载入DLL时所需的信息及DLL函数定位。 2.运行时动态链接(run-time dynamic linking),运行时可以通过LoadLibrary或Loa dLibraryEx函数载入DLL。DLL载入后,模块可以通过调用GetProcAddress取DLL函数的 出口地址,然后就可以通过返回的函数指针调用DLL函数了。如此即可避免导入库文件了 。 27.IP组播有那些好处? 答:Internet上产生的许多新的应用,特别是高带宽的多媒体应用,带来了带宽的急剧 消耗和网络拥挤问题。组播是一种允许一个或多个发送者(组播源)发送单一的数据包 到多个接收者(一次的,同时的)的网络技术。组播可以大大的节省网络带宽,因为无 论有多少个目标地址,在整个网络的任何一条链路上只传送单一的数据包。所以说组播 技术的核心就是针对如何节约网络资源的前提下保证服务质量。

4,356

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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