计算机网络课程设计指导书

上传人:仙*** 文档编号:34194292 上传时间:2021-10-20 格式:DOC 页数:34 大小:217.50KB
收藏 版权申诉 举报 下载
计算机网络课程设计指导书_第1页
第1页 / 共34页
计算机网络课程设计指导书_第2页
第2页 / 共34页
计算机网络课程设计指导书_第3页
第3页 / 共34页
资源描述:

《计算机网络课程设计指导书》由会员分享,可在线阅读,更多相关《计算机网络课程设计指导书(34页珍藏版)》请在装配图网上搜索。

1、1计算机网络课程设计指导书2前 言计算机网络课程是计算机科学与技术专业的重要专业课程之一。随着计算机网络技术的迅速发展和在当今信息社会中的广泛应用,给计算机网络课程的教学提出了新的更高的要求。由于计算机网络是一门实践性较强的技术,课堂教学应该与实践环节紧密结合。将计算机网络课程建设成一流的课程,是近期计算机网络课程努力的方向。希望同学们在使用本实验指导书及进行实验的过程中,能够帮助我们不断地发现问题,并提出建议,使计算机网络课程设计真正成为课堂教学的有益补充。同时也希望同学们能够充分利用实验条件,认真完成实验,从实验中得到应有的锻炼和培养。3目 录一、一、计算机网络计算机网络实验教学大纲实验教

2、学大纲.41.1 学时安排 .41.2 实验内容 .41.3 试验要求 .51.4 验收 .5二、实验一:二、实验一:PING 程序设计程序设计.52.1 实验目的 .52.2 实验内容 .52.3 实验步骤和注意事项 .6三、实验二:文件传输协议的简单设计与实现三、实验二:文件传输协议的简单设计与实现.63.1 实验目的 .63.2 实验内容和要求.73.3 注意事项 .7四、实验三:局域网截包程序设计四、实验三:局域网截包程序设计.84.1 实验目的 .84.2 实验内容 .84.3 实验步骤和注意事项 .8五、实验四:数据链路层协议的设计与实现五、实验四:数据链路层协议的设计与实现.85

3、.1 实验目的 .85.2 实验内容 .95.3 模拟实现环境 .95.4 实验步骤和注意事项 .10附录一:参考文献附录一:参考文献.11附录二:实验报告的格式附录二:实验报告的格式.12附录三、附录三、SOCKET 编程编程 .171、SOCKET 规范概述 .172、WINDOWS 环境下 SOCKET 基本函数.183、RAW 模式的 SOCKET 编程.224一、计算机网络实验教学大纲1.1 学时安排本课程设计安排两周时间。1.2 实验内容 计算机网络是现代信息社会最重要的基础设施之一。在过去十几年里得到了迅速的发展和应用。计算机网络课程实验的目的是为了使学生在课程学习的同时,通过在

4、一个计算机网络环境中的实际操作,对现代计算机网络的基本功能有一个初步的了解。通过一个简单的 PING 程序的设计和实现,理解 TCP/IP 协议的工作机制和编程方法;通过实现一个文件传输协议,掌握计算机网络应用层协议的基本实现技术;同时还提供了一些选做实验以供有余力有兴趣的同学进一步提高。总之,通过上述实验环节,使学生加深了解和更好地掌握计算机网络课程教学大纲要求的内容。计算机网络课程设计共提供了 4 个实验:实验一:PING 程序的设计与实现 该实验的主要目的是使同学们掌握基于 TCP/IP 网络编程的基本方法和思路,同时进一步熟悉计算机网络课程中基于 IP 层协议的工作机制。实验二: 文件

5、传输协议的简单设计与实现 文件传输是应用层中的一个主要协议,负责将主机中的文件从一台机器传送到另一台机器。文件传输协议 FTP 采用客户/服务器的工作模式,由客户端产生操作要求,服务器接收到该请求后返回响应。该实验的目的是使同学们掌握应用层协议的实现方法,加深对客户/服务器的工作模式的认识。实验三:局域网截包程序设计 局域网采用广播方式完成包的发送。因此任何机器发送的包,均可被局域网上的其它机器截获,只要将以太网卡设置为“混杂模式”即可。该实验的主要目的是对计算机网络课程的局域网以及 IP 等相关知识巩固和复习。实验四: 数据链路层协议的设计与实现计算机网络的数据链路层协议保证通信双方在有差错

6、的通信线路上进行无差错的数据传输,是计算机网络各层协议中通信控制功能最典型的一种协议,用于保证数据的可靠传输、进行流量5控制等基本功能。本实验实现一个数据链路层协议的数据传送部分,目的在于使学生更好地理解数据链路层协议中的“滑动窗口”技术的基本工作原理,掌握计算机网络协议的基本实现技术。1.3 实验要求在计算机网络的课程实验过程中,要求学生做到:(1)预习实验指导书有关部分,认真做好实验内容的准备,就实验可能出现的情况提前作出思考和分析。(2)仔细观察上机和上网操作时出现的各种现象,记录主要情况,作出必要说明和分析。(3)认真书写实验报告。实验报告包括实验目的和要求,实验环境及实验结果分析。对

7、需编程的实验,写出程序设计说明,给出源程序框图和清单。(4)遵守机房纪律,服从辅导教师指挥,爱护实验设备。(5)实验课程不迟到。如有事不能出席,所缺实验一般不补。1.4 验收实验的验收将分为两个部分:第一部分是上机操作,包括检查程序运行和即时提问第二部分是提交书面的实验报告此外,针对以前教学中出现的问题,网络实验将采用阶段检查阶段检查方式,每个实验都将应当在规定的时间内完成并检查通过,过期视为未完成该实验,不计成绩。以避免集中检查方式产生的诸多不良问题,希望同学们抓紧时间,合理安排,认真完成。二、实验一:PING 程序设计2.1 实验目的PING 程序是我们使用的比较多的用于测试网络连通性的程

8、序。PING 程序基于 ICMP,使用ICMP 的回送请求和回送应答来工作。由计算机网络课程知道,ICMP 是基于 IP 的一个协议,ICMP包通过 IP 的封装之后传递。课程设计中选取 PING 程序的设计,其目的是希望同学们通过 PING 程序的设计,能初步掌握TCP/IP 网络协议的基本实现方法,对网络的实现机制有进一步的认识。2.2 实验内容1、RAW 模式的 SOCKET 编程 PING 程序是面向用户的应用程序,该程序使用 ICMP 的封装机制,通过 IP 协议来工作。为了6实现直接对 IP 和 ICMP 包进行操作,实验中使用 RAW 模式的 SOCKET 编程。熟悉 SOCKE

9、T 的编程,包括基本的系统调用如 SOCKET、BIND 等(参考附录二) ;2、具体内容(1)定义数据结构 需要定义好 IP 数据报、ICMP 包等相关的数据结构(2)程序实现 在 WINDOWS 环境下实现 PING 程序(3)程序要求在命令提示符下输入: PING .其中 为目的主机的 IP 地址,不要求支持域名,对是否带有开关变量也不做要求。不带开关变量时,要求返回 4 次响应。返回信息的格式: REPLY FROM .或 REQUEST TimeOut (无法 PING 通的情况)2.3 实验步骤和注意事项实验按下述步骤进行:1)熟悉IP以及ICMP协议的工作机制2)熟悉RAW模式的

10、SOCKET编程3)编写PING的实现程序4)编译环境中需要包括SOCKET库 WS2_32.lib5)在模拟实现环境下调试并运行自己编写的PIN程序6)保留你实现的程序在你的用户目录下,以备辅导教师检查7)最后提交源程序,撰写实验报告三、实验二:文件传输协议的简单设计与实现3.1 实验目的文件传送是各种计算机网络都实现的基本功能,文件传送协议是一种最基本的应用层协议按照客户/服务器的模式进行工作,提供交互式的访问,是INTERNET使用最广泛的协议之一。7本实验的目的是,学会利用已有网络环境设计并实现简单应用层协议,掌握TCP/IP 网络应用程序基本的设计方法和实现技巧。3.2 实验内容和要

11、求1、实验内容我们的计算机网络实验环境建立在TCP/IP 网络体系结构之上。各计算机除了安装TCP/IP 软件外,还安装了TCP/IP 开发系统。实验室各计算机具备Windows环境中套接字socket 的编程接口功能,可为用户提供全网范围的进程通信功能。本实验要求学生利用这些功能,设计和实现一个简单的文件传送协议。2、具体要求用socket 编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(server.c),该程序应能实现下述命令功能:get:取远方的一个文件put:传给远方一个文件pwd:显示远主当前目录dir:列出远方当前目录cd :改变远方当前目录? :显示你提供

12、的命令quit :退出返回这此命令的具体工作方式(指给出结果的形式)可以参照FTP 的相应命令,有余力的同学可以多实现几个命令。最后,写出实验报告。3.3 注意事项1、关于端口号(假设用SERV_PORT 来表示)的设定,原则上2000 至5000都可用,为避免冲突,建议取你学号后三位数加上2000,比如学号为971234,则可定义: #define SERV_PORT 22342、客户和服务程序中要有相应的include 文件(参考所给例子程序)3、有些同学的server 方程序支持多连接,为了不占用更多的系统资源,并发连接数限制在3 个以内。4、最后提交源程序,撰写实验报告,在实验报告中说

13、明设计的思路8四、实验三:局域网截包程序设计4.1 实验目的目前的局域网基本上都采用以广播为技术基础的以太网,任何两个节点之间的通信数据包,不仅为这两个节点的网卡所接收,也同时为处在同一以太网上的任何一个节点的网卡所截取。因此,黑客只要接入以太网上的任一节点进行侦听,就可以捕获发生在这个以太网上的所有数据包,对其进行解包分析,从而窃取关键信息,这就是以太网所固有的安全隐患。网上主要的免费黑客攻击工具如 SATAN、ISS、NETCAT 等均将以太网侦听作为基本的手段。本实验实现一个局域网截包程序,目的在于使学生能更好地理解网络的工作机制(包括封包机制、协议分析等),该实验是对计算机网络课程一个

14、有益的补充。4.2 实验内容在一个局域网环境中,用C 语言实现下面的基本功能:(1)确定截包的方法:包括RAW 模式SOCKET、PACKET32以及直接作为驱动程序挂在NDIS上(2)要求截获以下包的类型并分析:以太网帧格式、IP包、ICMP包、TCP报文段、UDP报文等相关字段进行描述。4.3 实验步骤和注意事项实验按下述步骤进行:(1)熟悉RAW模式的SOCKET编程(2)熟悉PACKET32的工作机制(3)熟悉WINDOWS 2000环境下NDIS驱动程序的编写方法(4)编写基于上述某一机制的局域网截包的实现程序;(5)在模拟实现环境下调试并运行自己编写的协议实现程序;(6)如出现异常

15、情况,在实验报告中记录并分析可能的原因五、实验四:数据链路层协议的设计与实现5.1 实验目的计算机网络的数据链路层协议保证通信双方在有差错的通信线路上进行无差错的数据传输,是计算机网络各层协议中通信控制功能最典型的一种协议。本实验实现一个数据链路层协议的数据传送部分,目的在于使学生更好地理解数据链路层协议中的“滑动窗口”技术的基本工作原理,掌握计算机网络协议的基本实现技术。95.2 实验内容在一个数据链路层的模拟实现环境中,用C 语言实现下面两个数据链路层协议。(1)“退回到N 重发”的滑动窗口协议(参考文献1第四章的协议5);(2)“选择重发”的滑动滑动窗口协议(参考文献1第四章的协议6);

16、5.3 模拟实现环境数据链路层协议位于物理层之上,网络层之下。它使用物理层提供的服务,并且向网络层的分组数据传输提供可靠的服务。由于构造实际的工作环境需要系统提供支持,难度较大。因此,实现一个数据链路层协议必须要有一个模拟实现环境。在本实验中,我们仍然采用基于SOCKET的模拟通信环境。这个模拟系统由以下几部分组成:两个代码文件sim.c 和worker.c;一个通用的头文件common.h,包含类型预定义、常量定义等;协议文件使用的头文件potocol.h,包含支撑函数的函数声明等。模拟系统使用三个进程:main: 控制整个模拟系统。MO: 协议2 和协议3 的发送方(machine 0)。

17、M1: 协议2 和协议3 的接收方(machine 1)。文件sim.c 中包含着主程序,它首先分析命令行并且将参数保存起来,接着创建六个管道使得三个进程之间能够进行通信,所创建的文件描述字以如下方式命名:MO 和M1 的通信;w1、r1:MO 到M1 的帧传递w2、r2:M1 到MO 的帧传递Main 和MO 的通信:W3、r3:main 通知MO go-aheadw4、r4:MO 通知main,MO 已准备好Main 和M1 通信:w5、r5: main 通知M1-go-aheadw6、r6:M1 通知main,M1 已准备好。模拟实现环境的源程序放置在相应的目录下,请同学们首先把这些文件

18、拷贝到自己的用户目录下。105.4 实验步骤和注意事项实验按下述步骤进行:(1)熟悉已给出的数据链路层协议模拟实现环境的功能;(2)编写两个数据链路层协议的实现程序;(3)在模拟实现环境下调试并运行自己编写的协议实现程序;(4)了解协议的工作轨迹,如出现异常情况,在实验报告中写出原因分析;(5)保留你实现的数据链路层协议在你的用户目录下,以备辅导教师检查。11附录一:参考文献参考文献1“Computer Networks (Third Edition)”, Andrew S. Tanenbaum, Prentice-Hall, 清华大学出版社影印, 1996中译本计算机网络,熊桂喜等译,清华大

19、学出版社,1998参考文献2TCP/IP 网络原理与技术,周明天、汪文勇编著,清华大学出版社,1993参考文献3计算机网络(第3版),谢希仁编著,大连理工大学出版社,200012附录二:实验报告的格式实验报告课 程 实验名称 专业班级 姓 名 学 号 同组人姓名 同组人学号 实验日期 教师审批签字 二 零 零 三 年 月 日13一、实验目的和要求1、实验目的2、实验要求14二、实验环境15三、程序的逻辑框图16四、程序源代码17五、实验数据、结果分析六、总结七、教师意见18附录三、SOCKET 编程1、SOCKET 规范概述Windows Sockets 规范以 U.C. Berkeley 大

20、学 BSD UNIX 中流行的 Socket 接口为范例定义了一套 Micosoft Windows 下网络编程接口。它不仅包含了人们所熟悉的 Berkeley Socket 风格的库函数;也包含了一组针对 Windows 的扩展库函数,以使程序员能充分地利用 Windows 消息驱动机制进行编程。Windows Sockets 规范本意在于提供给应用程序开发者一套简单的 API,并让各家网络软件供应商共同遵守。此外,在一个特定版本 Windows 的基础上,Windows Sockets 也定义了一个二进制接口(ABI),以此来保证应用 Windows Sockets API 的应用程序能够

21、在任何网络软件供应商的符合 Windows Sockets 协议的实现上工作。因此这份规范定义了应用程序开发者能够使用,并且网络软件供应商能够实现的一套库函数调用和相关语义。遵守这套 Windows Sockets 规范的网络软件,我们称之为 Windows Sockets 兼容的,而Windows Sockets 兼容实现的提供者,我们称之为 Windows Sockets 提供者。一个网络软件供应商必须百分之百地实现 Windows Sockets 规范才能做到现 Windows Sockets 兼容。任何能够与 Windows Sockets 兼容实现协同工作的应用程序就被认为是具有 W

22、indows Sockets 接口。我们称这种应用程序为 Windows Sockets 应用程序。Windows Sockets 规范定义并记录了如何使用 API 与 Internet 协议族(IPS,通常我们指的是TCP/IP)连接,尤其要指出的是所有的 Windows Sockets 实现都支持流套接口和数据报套接口. 应用程序调用 Windows Sockets 的 API 实现相互之间的通讯。Windows Sockets 又利用下层的网络通讯协议功能和操作系统调用实现实际的通讯工作。它们之间的关系如下图:应用程序 1应用程序 N网络编程截面,如 WINDOWS SOCKET网络通信

23、协议服务截面,如 TCP/IP操作系统,如 WINDOWS物理通信介质192、WINDOWS 环境下 SOCKET 基本函数(1)WSAStartup 函数int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData); 使用 Socket 的程序在使用 Socket 之前必须调用 WSAStartup 函数。该函数的第一个参数指明程序请求使用的 Socket 版本,其中高位字节指明副版本、低位字节指明主版本;操作系统利用第二个参数返回请求的 Socket 的版本信息。当一个应用程序调用 WSAStartup 函数时,操作系统根据请求的 S

24、ocket 版本来搜索相应的 Socket 库,然后绑定找到的 Socket 库到该应用程序中。以后应用程序就可以调用所请求的 Socket 库中的其它 Socket 函数了。该函数执行成功后返回 0。 例:假如一个程序要使用 2.1 版本的 Socket,那么程序代码如下wVersionRequested = MAKEWORD( 2, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); (2)WSACleanup 函数 int WSACleanup (void); 应用程序在完成对请求的 Socket 库的使用后,要调用 WSAClea

25、nup 函数来解除与 Socket 库的绑定并且释放 Socket 库所占用的系统资源。 (3)socket 函数SOCKET socket( int af, int type, int protocol ); 应用程序调用 socket 函数来创建一个能够进行网络通信的套接字。第一个参数指定应用程序使用的通信协议的协议族,对于 TCP/IP 协议族,该参数置 PF_INET;第二个参数指定要创建的套接字类型,流套接字类型为 SOCK_STREAM、数据报套接字类型为 SOCK_DGRAM;第三个参数指定应用程序所使用的通信协议。该函数如果调用成功就返回新创建的套接字的描述符,如果失败就返回I

26、NVALID_SOCKET。套接字描述符是一个整数类型的值。每个进程的进程空间里都有一个套接字描述符表,该表中存放着套接字描述符和套接字数据结构的对应关系。该表中有一个字段存放新创建的套接字的描述符,另一个字段存放套接字数据结构的地址,因此根据套接字描述符就可以找到其对应的套接字数据结构。每个进程在自己的进程空间里都有一个套接字描述符表但是套接字数据结构都是在操作系统的内核缓冲里。下面是一个创建流套接字的例子: struct protoent *ppe; ppe=getprotobyname(tcp); SOCKET ListenSocket=socket(PF_INET,SOCK_STREA

27、M,ppe-p_proto); (4)closesocket 函数 int closesocket( SOCKET s ); 20closesocket 函数用来关闭一个描述符为 s 套接字。由于每个进程中都有一个套接字描述符表,表中的每个套接字描述符都对应了一个位于操作系统缓冲区中的套接字数据结构,因此有可能有几个套接字描述符指向同一个套接字数据结构。套接字数据结构中专门有一个字段存放该结构的被引用次数,即有多少个套接字描述符指向该结构。当调用 closesocket 函数时,操作系统先检查套接字数据结构中的该字段的值,如果为 1,就表明只有一个套接字描述符指向它,因此操作系统就先把 s 在

28、套接字描述符表中对应的那条表项清除,并且释放 s 对应的套接字数据结构;如果该字段大于 1,那么操作系统仅仅清除 s 在套接字描述符表中的对应表项,并且把 s 对应的套接字数据结构的引用次数减 1。 closesocket 函数如果执行成功就返回 0,否则返回 SOCKET_ERROR。 (5)send 函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用 send 函数来向 TCP 连接的另一端发送数据。客户程序一般用 send 函数向服务器发送请求,而服务器则通常用 send 函

29、数来向客户程序发送应答。该函数的第一个参数指定发送端套接字描述符;第二个参数指明一个存放应用程序要发送数据的缓冲区;第三个参数指明实际要发送的数据的字节数;第四个参数一般置 0。这里只描述同步 Socket 的send 函数的执行流程。当调用该函数时,send 先比较待发送数据的长度 len 和套接字 s 的发送缓冲区的长度,如果 len 大于 s 的发送缓冲区的长度,该函数返回 SOCKET_ERROR;如果 len 小于或者等于 s 的发送缓冲区的长度,那么 send 先检查协议是否正在发送 s 的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送 s 的发送缓冲中的数

30、据或者 s 的发送缓冲中没有数据,那么 send 就比较 s 的发送缓冲区的剩余空间和 len,如果 len 大于剩余空间大小send 就一直等待协议把 s 的发送缓冲中的数据发送完,如果 len 小于剩余空间大小 send 就仅仅把buf 中的数据 copy 到剩余空间里(注意并不是 send 把 s 的发送缓冲中的数据传到连接的另一端的,而是协议传的,send 仅仅是把 buf 中的数据 copy 到 s 的发送缓冲区的剩余空间里)。如果 send函数 copy 数据成功,就返回实际 copy 的字节数,如果 send 在 copy 数据时出现错误,那么 send就返回 SOCKET_ER

31、ROR;如果 send 在等待协议传送数据时网络断开的话,那么 send 函数也返回SOCKET_ERROR。要注意 send 函数把 buf 中的数据成功 copy 到 s 的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。如果协议在后续的传送过程中出现网络错误的话,那么下一个 Socket 函数就会返回 SOCKET_ERROR。(每一个除 send 外的 Socket函数在执行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,如果在等待时出现网络错误,那么该 Socket 函数就返回 SOCKET_ERROR) 注意:在 Unix 系统下

32、,如果 send 在等待协议传送数据时网络断开的话,调用 send 的进程会接收到一个 SIGPIPE 信号,进程对该信号的默认处理是进程终止。 21(6)recv 函数 int recv( SOCKET s, char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用 recv 函数从 TCP 连接的另一端接收数据。该函数的第一个参数指定接收端套接字描述符;第二个参数指明一个缓冲区,该缓冲区用来存放 recv 函数接收到的数据;第三个参数指明 buf 的长度;第四个参数一般置 0。这里只描述同步 Socket 的 recv 函数的执行流程。当应

33、用程序调用 recv 函数时,recv 先等待 s 的发送缓冲中的数据被协议传送完毕,如果协议在传送 s 的发送缓冲中的数据时出现网络错误,那么 recv 函数返回 SOCKET_ERROR,如果s 的发送缓冲中没有数据或者数据被协议成功发送完毕后,recv 先检查套接字 s 的接收缓冲区,如果 s 接收缓冲区中没有数据或者协议正在接收数据,那么 recv 就一直等待,只到协议把数据接收完毕。当协议把数据接收完毕,recv 函数就把 s 的接收缓冲中的数据 copy 到 buf 中(注意协议接收到的数据可能大于 buf 的长度,所以在这种情况下要调用几次 recv 函数才能把 s 的接收缓冲中

34、的数据 copy 完。recv 函数仅仅是 copy 数据,真正的接收数据是协议来完成的),recv 函数返回其实际 copy 的字节数。如果 recv 在 copy 时出错,那么它返回 SOCKET_ERROR;如果 recv 函数在等待协议接收数据时网络中断了,那么它返回 0。 注意:在 Unix 系统下,如果 recv 函数在等待协议接收数据时网络断开了,那么调用 recv 的进程会接收到一个 SIGPIPE 信号,进程对该信号的默认处理是进程终止。 (7)bind 函数 int bind( SOCKET s, const struct sockaddr FAR *name, int n

35、amelen ); 当创建了一个 Socket 以后,套接字数据结构中有一个默认的 IP 地址和默认的端口号。一个服务程序必须调用 bind 函数来给其绑定一个 IP 地址和一个特定的端口号。客户程序一般不必调用 bind 函数来为其 Socket 绑定 IP 地址和断口号。该函数的第一个参数指定待绑定的 Socket 描述符;第二个参数指定一个 sockaddr 结构,该结构是这样定义的: struct sockaddr u_short sa_family; char sa_data14; ; sa_family 指定地址族,对于 TCP/IP 协议族的套接字,给其置 AF_INET。当对

36、TCP/IP 协议族的套接字进行绑定时,我们通常使用另一个地址结构: struct sockaddr_in short sin_family; u_short sin_port; struct in_addr sin_addr; 22char sin_zero8; ; 其中 sin_family 置 AF_INET;sin_port 指明端口号;sin_addr 结构体中只有一个唯一的字段s_addr,表示 IP 地址,该字段是一个整数,一般用函数 inet_addr()把字符串形式的 IP 地址转换成 unsigned long 型的整数值后再置给 s_addr。有的服务器是多宿主机,至少有

37、两个网卡,那么运行在这样的服务器上的服务程序在为其 Socket 绑定 IP 地址时可以把 htonl(INADDR_ANY)置给s_addr,这样做的好处是不论哪个网段上的客户程序都能与该服务程序通信;如果只给运行在多宿主机上的服务程序的 Socket 绑定一个固定的 IP 地址,那么就只有与该 IP 地址处于同一个网段上的客户程序才能与该服务程序通信。我们用 0 来填充 sin_zero 数组,目的是让 sockaddr_in 结构的大小与 sockaddr 结构的大小一致。下面是一个 bind 函数调用的例子: struct sockaddr_in saddr; saddr.sin_fa

38、mily = AF_INET; saddr.sin_port = htons(8888); saddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(ListenSocket,(struct sockaddr *)&saddr,sizeof(saddr); (8)listen 函数 int listen( SOCKET s, int backlog ); 服务程序可以调用 listen 函数使其流套接字 s 处于监听状态。处于监听状态的流套接字 s 将维护一个客户连接请求队列,该队列最多容纳 backlog 个客户连接请求。假如该函数执行成功,则返回 0;

39、如果执行失败,则返回 SOCKET_ERROR。 (9)accept 函数 SOCKET accept( SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen ); 服务程序调用 accept 函数从处于监听状态的流套接字 s 的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道,如果连接成功,就返回新创建的套接字的描述符,以后与客户套接字交换数据的是新创建的套接字;如果失败就返回INVALID_SOCKET。该函数的第一个参数指定处于监听状态的流套接字;操作系统利用第二个参数来返回新创建的套接字

40、的地址结构;操作系统利用第三个参数来返回新创建的套接字的地址结构的长度。下面是一个调用 accept 的例子:struct sockaddr_in ServerSocketAddr; int addrlen; addrlen=sizeof(ServerSocketAddr); 23ServerSocket=accept(ListenSocket,(struct sockaddr *)&ServerSocketAddr,&addrlen); (10)connect 函数 int connect( SOCKET s, const struct sockaddr FAR *name, int nam

41、elen ); 客户程序调用 connect 函数来使客户 Socket s 与监听于 name 所指定的计算机的特定端口上的服务 Socket 进行连接。如果连接成功,connect 返回 0;如果失败则返回 SOCKET_ERROR。下面是一个例子: struct sockaddr_in daddr; memset(void *)&daddr,0,sizeof(daddr); daddr.sin_family=AF_INET; daddr.sin_port=htons(8888); daddr.sin_addr.s_addr=inet_addr(133.197.22.4); connect

42、(ClientSocket,(struct sockaddr *)&daddr,sizeof(daddr); 3、RAW 模式的 SOCKET 编程Windows Sockets 是一个编程接口,它是在加州大学伯克利分校开发的套接字接口的基础上定义的。它包括了一组扩展件,以充分利用 Microsoft Windows 消息驱动的特点。规范的 1.1 版是在 1993 年 1 月发行的,2.2.0 版在 1996 年 5 月发行。Windows 2000 支持 Winsock 2.2 版。在 Winsock2 中,支持多个传输协议的原始套接字,重叠 I/O 模型、服务质量控制等。这里介绍 Win

43、dows Sockets 的一些关于原始套接字(Raw Socket)的编程。同 Winsock 1 相比,最明显的就是支持了 Raw Socket 套接字类型,通过原始套接字,我们可以更加自如地控制Windows 下的多种协议,而且能够对网络底层的传输机制进行控制。(1)创建一个原始套接字,并设置 IP 头选项。SOCKET sock;sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);或者:s = WSASoccket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);这里,我们设置了 SOCK

44、_RAW 标志,表示我们声明的是一个原始套接字类型。创建原始套接字后,IP 头就会包含在接收的数据中,如果我们设定 IP_HDRINCL 选项,那么,就需要自己来构造 IP 头。注意,如果设置 IP_HDRINCL 选项,那么必须具有 administrator 权限,要不就必须修改24注册表:HKEY_LOCAL_MACHINESystemCurrentControlSetServicesAfdParameter修改键:DisableRawSecurity(类型为 DWORD),把值修改为 1。如果没有,就添加。BOOL blnFlag=TRUE;setsockopt(sock, IPPRO

45、TO_IP, IP_HDRINCL, (char *)&blnFlag, sizeof(blnFlag);对于原始套接字在接收数据报的时候,要注意这么几点:如果接收的数据报中协议类型和定义的原始套接字匹配,那么,接收的所有数据就拷贝到套接字中。如果绑定了本地地址,那么只有接收数据 IP 头中对应的远端地址匹配,接收的数据就拷贝到套接字中。如果定义的是外部地址,比如使用 connect(),那么,只有接收数据 IP 头中对应的源地址匹配,接收的数据就拷贝到套接字中。(2)构造 IP 头和 TCP 头这里,提供 IP 头和 TCP 头的结构:/ Standard TCP flags#define

46、URG 0 x20#define ACK 0 x10#define PSH 0 x08#define RST 0 x04#define SYN 0 x02#define FIN 0 x01typedef struct _iphdr /定义 IP 首部unsigned char h_lenver; /4 位首部长度+4 位 IP 版本号unsigned char tos; /8 位服务类型 TOSunsigned short total_len; /16 位总长度(字节)unsigned short ident; /16 位标识unsigned short frag_and_flags; /3

47、位标志位unsigned char ttl; /8 位生存时间 TTLunsigned char proto; /8 位协议 (TCP, UDP 或其他)unsigned short checksum; /16 位 IP 首部校验和unsigned int sourceIP; /32 位源 IP 地址unsigned int destIP; /32 位目的 IP 地址IP_HEADER;25typedef struct psd_hdr /定义 TCP 伪首部unsigned long saddr; /源地址unsigned long daddr; /目的地址char mbz;char ptcl

48、; /协议类型 unsigned short tcpl; /TCP 长度PSD_HEADER;typedef struct _tcphdr /定义 TCP 首部USHORT th_sport; /16 位源端口USHORT th_dport; /16 位目的端口unsigned int th_seq; /32 位序列号unsigned int th_ack; /32 位确认号unsigned char th_lenres; /4 位首部长度/6 位保留字unsigned char th_flag; /6 位标志位USHORT th_win; /16 位窗口大小USHORT th_sum; /1

49、6 位校验和USHORT th_urp; /16 位紧急数据偏移量TCP_HEADER;TCP 伪首部并不是真正存在的,只是用于计算检验和。校验和函数:USHORT checksum(USHORT *buffer, int size)unsigned long cksum=0;while (size 1)cksum += *buffer+;size -= sizeof(USHORT); if (size)26cksum += *(UCHAR*)buffer; cksum = (cksum 16) + (cksum & 0 xffff);cksum += (cksum 16); return (

50、USHORT)(cksum); 当需要自己填充 IP 头部和 TCP 头部的时候,就同时需要自己计算他们的检验和。(3)发送原始套接字数据报填充这些头部稍微麻烦点,发送就相对简单多了。只需要使用 sendto()就 OK。sendto(sock, (char*)&tcpHeader, sizeof(tcpHeader), 0,(sockaddr*)&addr_in,sizeof(addr_in);(4)接收数据和发送原始套接字数据相比,接收就比较麻烦了。因为在 WIN 我们不能用 recv()来接收 raw socket 上的数据,这是因为,所有的 IP 包都是先递交给系统核心,然后再传输到用

51、户程序,当发送一个 raws socket 包的时候(比如 syn),核心并不知道,也没有这个数据被发送或者连接建立的记录,因此,当远端主机回应的时候,系统核心就把这些包都全部丢掉,从而到不了应用程序上。所以,就不能简单地使用接收函数来接收这些数据报。要达到接收数据的目的,就必须采用嗅探,接收所有通过的数据包,然后进行筛选,留下符合我们需要的。可以再定义一个原始套接字,用来完成接收数据的任务,需要设置 SIO_RCVALL,表示接收所有的数据。27什么是什么是 Socket Socket 接口是接口是 TCP/IP 网络的网络的 API,Socket 接口定义了许多函数或例程,程序员可以用接口

52、定义了许多函数或例程,程序员可以用它们来开发它们来开发 TCP/IP 网络上的应用程序。要学网络上的应用程序。要学 Internet 上的上的 TCP/IP 网络编程,必须理解网络编程,必须理解Socket 接口。接口。 Socket 接口设计者最先是将接口放在接口设计者最先是将接口放在 Unix 操作系统里面的。如果了解操作系统里面的。如果了解 Unix 系统的输入系统的输入和输出的话,就很容易了解和输出的话,就很容易了解 Socket 了。网络的了。网络的 Socket 数据传输是一种特殊的数据传输是一种特殊的 I/O,Socket也是一种文件描述符。也是一种文件描述符。Socket 也具

53、有一个类似于打开文件的函数调用也具有一个类似于打开文件的函数调用 Socket(),该函数返回,该函数返回一个整型的一个整型的 Socket 描述符,随后的连接建立、数据传输等操作都是通过该描述符,随后的连接建立、数据传输等操作都是通过该 Socket 实现的。常实现的。常用的用的 Socket 类型有两种:流式类型有两种:流式 Socket(SOCK_STREAM)和数据报式)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的)。流式是一种面向连接的 Socket,针对于面向连接的,针对于面向连接的 TCP 服务服务应用;数据报式应用;数据报式 Socket 是一种无连接的

54、是一种无连接的 Socket,对应于无连接的,对应于无连接的 UDP 服务应用。服务应用。 Socket 建立建立 为了建立为了建立 Socket,程序可以调用,程序可以调用 Socket 函数,该函数返回一个类似于文件描述符的句柄。函数,该函数返回一个类似于文件描述符的句柄。socket 函数原型为:函数原型为: int socket(int domain, int type, int protocol); domain 指明所使用的协议族,通常为指明所使用的协议族,通常为 PF_INET,表示互联网协议族(,表示互联网协议族(TCP/IP 协议族);协议族);type 参数指定参数指定 s

55、ocket 的类型:的类型:SOCK_STREAM 或或 SOCK_DGRAM,Socket 接口还定义接口还定义了原始了原始 Socket(SOCK_RAW),允许程序使用低层协议;),允许程序使用低层协议;protocol 通常赋值通常赋值0。Socket()调用返回一个整型调用返回一个整型 socket 描述符,你可以在后面的调用使用它。描述符,你可以在后面的调用使用它。 Socket 描述符是一个指向内部数据结构的指针,它指向描述符表入口。调用描述符是一个指向内部数据结构的指针,它指向描述符表入口。调用 Socket 函数函数时,时,socket 执行体将建立一个执行体将建立一个 So

56、cket,实际上,实际上建立一个建立一个 Socket意味着为一个意味着为一个 Socket 数数据结构分配存储空间。据结构分配存储空间。Socket 执行体为你管理描述符表。执行体为你管理描述符表。 两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。远端主机地址和远端协议端口。Socket 数据结构中包含这五种信息。数据结构中包含这五种信息。 Socket 配置配置 通过通过 socket 调用返回一个调用返回一个 socket 描述符后,在使用描述符

57、后,在使用 socket 进行网络传输以前,必须配进行网络传输以前,必须配置该置该 socket。面向连接的。面向连接的 socket 客户端通过调用客户端通过调用 Connect 函数在函数在 socket 数据结构中保存数据结构中保存本地和远端信息。无连接本地和远端信息。无连接 socket 的客户端和服务端以及面向连接的客户端和服务端以及面向连接 socket 的服务端通过调用的服务端通过调用bind 函数来配置本地信息。函数来配置本地信息。 Bind 函数将函数将 socket 与本机上的一个端口相关联,随后你就可以在该端口监听服务请求。与本机上的一个端口相关联,随后你就可以在该端口监

58、听服务请求。Bind函数原型为:函数原型为: int bind(int sockfd,struct sockaddr *my_addr, int addrlen); Sockfd 是调用是调用 socket 函数返回的函数返回的 socket 描述符描述符,my_addr 是一个指向包含有本机是一个指向包含有本机 IP地址及端口号等信息的地址及端口号等信息的 sockaddr 类型的指针;类型的指针;addrlen 常被设置为常被设置为 sizeof(struct sockaddr)。 struct sockaddr 结构类型是用来保存结构类型是用来保存 socket 信息的:信息的: str

59、uct sockaddr unsigned short sa_family; /* 地址族,地址族, AF_xxx */ char sa_data14; /* 14 字节的协议地址字节的协议地址 */ ; sa_family 一般为一般为 AF_INET,代表,代表 Internet(TCP/IP)地址族;)地址族;sa_data 则包含该则包含该socket 的的 IP 地址和端口号。地址和端口号。 另外还有一种结构类型:另外还有一种结构类型: struct sockaddr_in short int sin_family; /* 地址族地址族 */ unsigned short int s

60、in_port; /* 端口号端口号 */ 28 struct in_addr sin_addr; /* IP 地址地址 */ unsigned char sin_zero8; /* 填充填充 0 以保持与以保持与 struct sockaddr 同样大小同样大小 */ ; 这个结构更方便使用。这个结构更方便使用。sin_zero 用来将用来将 sockaddr_in 结构填充到与结构填充到与 struct sockaddr同样的长度,可以用同样的长度,可以用 bzero()或或 memset()函数将其置为零。指向函数将其置为零。指向 sockaddr_in 的指针和指的指针和指向向 soc

61、kaddr 的指针可以相互转换,这意味着如果一个函数所需参数类型是的指针可以相互转换,这意味着如果一个函数所需参数类型是 sockaddr 时,你时,你可以在函数调用的时候将一个指向可以在函数调用的时候将一个指向 sockaddr_in 的指针转换为指向的指针转换为指向 sockaddr 的指针;或者相的指针;或者相反。反。 使用使用 bind 函数时,可以用下面的赋值实现自动获得本机函数时,可以用下面的赋值实现自动获得本机 IP 地址和随机获取一个没有被占用地址和随机获取一个没有被占用的端口号:的端口号: my_addr.sin_port = 0; /* 系统随机选择一个未被使用的端口号系统

62、随机选择一个未被使用的端口号 */ my_addr.sin_addr.s_addr = INADDR_ANY; /* 填入本机填入本机 IP 地址地址 */ 通过将通过将 my_addr.sin_port 置为置为 0,函数会自动为你选择一个未占用的端口来使用。同样,通,函数会自动为你选择一个未占用的端口来使用。同样,通过将过将 my_addr.sin_addr.s_addr 置为置为 INADDR_ANY,系统会自动填入本机,系统会自动填入本机 IP 地址。地址。 注意在使用注意在使用 bind 函数是需要将函数是需要将 sin_port 和和 sin_addr 转换成为网络字节优先顺序;而

63、转换成为网络字节优先顺序;而sin_addr 则不需要转换。则不需要转换。 计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。Internet 上数据以高上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在Internet 上传输数据时就需要进行转换,否则就会出现数据不一致。上传输数据时就需要进行转换,否则就会出现数据不一致。 下面是几个字节顺序转换函数:下面是几个字节顺序转换函数: htonl():把:

64、把 32 位值从主机字节序转换成网络字节序位值从主机字节序转换成网络字节序 htons():把:把 16 位值从主机字节序转换成网络字节序位值从主机字节序转换成网络字节序 ntohl():把:把 32 位值从网络字节序转换成主机字节序位值从网络字节序转换成主机字节序 ntohs():把:把 16 位值从网络字节序转换成主机字节序位值从网络字节序转换成主机字节序 Bind()函数在成功被调用时返回函数在成功被调用时返回 0;出现错误时返回;出现错误时返回-1并将并将 errno 置为相应的错误号。置为相应的错误号。需要注意的是,在调用需要注意的是,在调用 bind 函数时一般不要将端口号置为小于

65、函数时一般不要将端口号置为小于 1024 的值,因为的值,因为 1 到到 1024 是是保留端口号,你可以选择大于保留端口号,你可以选择大于 1024 中的任何一个没有被占用的端口号。中的任何一个没有被占用的端口号。 连接建立连接建立 面向连接的客户程序使用面向连接的客户程序使用 Connect 函数来配置函数来配置 socket 并与远端服务器建立一个并与远端服务器建立一个 TCP 连接,连接,其函数原型为:其函数原型为: int connect(int sockfd, struct sockaddr *serv_addr,int addrlen); Sockfd 是是 socket 函数返

66、回的函数返回的 socket 描述符;描述符;serv_addr 是包含远端主机是包含远端主机 IP 地址和端口地址和端口号的指针;号的指针;addrlen 是远端地质结构的长度。是远端地质结构的长度。Connect 函数在出现错误时返回函数在出现错误时返回-1,并且设置,并且设置errno 为相应的错误码。进行客户端程序设计无须调用为相应的错误码。进行客户端程序设计无须调用 bind(),因为这种情况下只需知道目的,因为这种情况下只需知道目的机器的机器的 IP 地址,而客户通过哪个端口与服务器建立连接并不需要关心,地址,而客户通过哪个端口与服务器建立连接并不需要关心,socket 执行体为你的程执行体为你的程序自动选择一个未被占用的端口,并通知你的程序数据什么时候到打断口。序自动选择一个未被占用的端口,并通知你的程序数据什么时候到打断口。 Connect 函数启动和远端主机的直接连接。只有面向连接的客户程序使用函数启动和远端主机的直接连接。只有面向连接的客户程序使用 socket 时才需要时才需要将此将此 socket 与远端主机相连。无连接协议从不建立直接连接。面向连接的服务器也从

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!