计算机网络课程设计指导书11计算机网络工程Word格式.docx

上传人:b****6 文档编号:21636353 上传时间:2023-01-31 格式:DOCX 页数:33 大小:54.84KB
下载 相关 举报
计算机网络课程设计指导书11计算机网络工程Word格式.docx_第1页
第1页 / 共33页
计算机网络课程设计指导书11计算机网络工程Word格式.docx_第2页
第2页 / 共33页
计算机网络课程设计指导书11计算机网络工程Word格式.docx_第3页
第3页 / 共33页
计算机网络课程设计指导书11计算机网络工程Word格式.docx_第4页
第4页 / 共33页
计算机网络课程设计指导书11计算机网络工程Word格式.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

计算机网络课程设计指导书11计算机网络工程Word格式.docx

《计算机网络课程设计指导书11计算机网络工程Word格式.docx》由会员分享,可在线阅读,更多相关《计算机网络课程设计指导书11计算机网络工程Word格式.docx(33页珍藏版)》请在冰豆网上搜索。

计算机网络课程设计指导书11计算机网络工程Word格式.docx

如图1所示的QuickPing程序。

图1QuickPing运行界面效果图

3、基于IP多播的网络会议程序

参照附录3的局域网IP多播程序,设计一个图形界面的网络会议程序(实现文本多播方式即可)。

4、网络嗅探器的设计与实现

参照附录4rawsocket编程例子,设计一个可以监视网络的状态、数据流动情况以及网络上传输的信息的网络嗅探器。

5、电子邮件客户端程序设计与实现

参照教材6.5节原理,设计一个电子邮件客户端程序。

6、TELNET终端设计与实现

参照RFC854、RFC855文档,设计一个TELNET终端程序。

7、网络代理服务器的设计与实现

实现一个简易的proxy程序。

proxy程序的功能:

能够做“二传手”的工作。

它自身处在能同时连通外界目标服务器和我的机器的位置上。

我的机器把请求发送给它,它接受请求,把请求原封不动的抄下来发送给外界目标服务器;

外界目标服务器响应了请求,把回答发送给它,它再接受回答,把回答原封不动的抄下来发送给我的机器。

这样,我的机器实际上是把它当作了目标服务器(由于是原封不动的转抄,请求和回答没有被修改)。

而它则是外界目标服务器的客户端。

四、推荐参考文献

[1]谢希仁,计算机网络(第五版),电子工业出版社,2008.

[2]AndrewS.Tanenbaum.计算机网络(第四版)[M].北京:

清华大学出版社,2004.

[3]中国Linux论坛:

[4]UNIX技术网站(永远的UNIX):

[5]Google

[6]蒋清明,C语言程序设计,人民邮电出版社,2008.

[7]陈维兴,林小茶,C++面向对象程序设计(第二版),中国铁道出版社,2009年12月

五、附录

附录1:

WindowsSocket编程简介

附录2:

PING源代码

附录3:

用VisualC++实现局域网IP多播

附录4:

rawsocket编程例子(基于LINUX操作系统)

附录5:

课程设计报告封面设计

附录1、WindowsSocket编程简介

使用WinSockAPI的编程,应该了解TCP/IP的基础知识。

虽然你可以直接使用WinSockAPI来写网络应用程序,但是,要写出优秀的网络应用程序,还是必须对TCP/IP协议有一些了解的。

1.TCP/IP协议与WinSock网络编程接口的关系

WinSock并不是一种网络协议,它只是一个网络编程接口,也就是说,它不是协议,但是它可以访问很多种网络协议,你可以把它当作一些协议的封装。

现在的WinSock已经基本上实现了与协议无关。

你可以使用WinSock来调用多种协议的功能。

那么,WinSock和TCP/IP协议到底是什么关系呢?

实际上,WinSock就是TCP/IP协议的一种封装,你可以通过调用WinSock的接口函数来调用TCP/IP的各种功能.例如我想用TCP/IP协议发送数据,你就可以使用WinSock的接口函数Send()来调用TCP/IP的发送数据功能,至于具体怎么发送数据,WinSock已经帮你封装好了这种功能。

2、TCP/IP协议介绍

TCP/IP协议包含的范围非常的广,它是一种四层协议,包含了各种硬件、软件需求的定义。

TCP/IP协议确切的说法应该是TCP/UDP/IP协议。

UDP协议(UserDatagramProtocol用户数据报协议),是一种保护消息边界的,不保障可靠数据的传输。

TCP协议(TransmissionControlProtocol传输控制协议),是一种流传输的协议。

他提供可靠的、有序的、双向的、面向连接的传输。

保护消息边界,就是指传输协议把数据当作一条独立的消息在网上传输,接收端只能接收独立的消息。

也就是说存在保护消息边界,接收端一次只能接收发送端发出的一个数据包。

而面向流则是指无保护消息边界的,如果发送端连续发送数据,接收端有可能在一次接收动作中,会接收两个或者更多的数据包。

举例来说,假如,我们连续发送三个数据包,大小分别是2k、4k、8k,这三个数据包都已经到达了接收端的网络堆栈中,如果使用UDP协议,不管我们使用多大的接收缓冲区去接收数据,我们必须有三次接收动作,才能够把所有的数据包接收完。

而使用TCP协议,我们只要把接收的缓冲区大小设置在14k以上,我们就能够一次把所有的数据包接收下来,只需要有一次接收动作。

这就是因为UDP协议的保护消息边界使得每一个消息都是独立的。

而流传输,却把数据当作一串数据流,它不认为数据是一个一个的消息。

所以有很多人在使用TCP协议通讯的时候,并不清楚TCP是基于流的传输,当连续发送数据的时候,他们时常会认识TCP会丢包。

其实不然,因为当它们使用的缓冲区足够大时,它们有可能会一次接收到两个甚至更多的数据包,而很多人往往会忽视这一点,只解析检查了第一个数据包,而已经接收的其它据包却被忽略了。

3.WinSock编程简单流程

WinSock编程分为服务器端和客户端两部分,TCP服务器端的大体流程如下:

对于任何基于WinSock的编程首先必须要初始化WinSockDLL库。

intWSAStarup(WORDwVersionRequested,LPWSADATAlpWsAData)。

wVersionRequested是我们要求使用的WinSock的版本。

调用这个接口函数可以初始化WinSock。

然后必须创建一个套接字(Socket)。

SOCKETSocket(intaf,inttype,intprotocol);

套接字可以说是WinSock通讯的核心。

WinSock通讯的所有数据传输,都是通过套接字来完成的,套接字包含了两个信息,一个是IP地址,一个是Port端口号,使用这两个信息,就可以确定网络中的任何一个通讯节点。

当调用了Socket()接口函数创建了一个套接字后,必须把套接字与你需要进行通讯的地址建立联系,可以通过绑定函数bind来实现这种联系。

intbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);

structsockaddr_in{

shortsin_family;

u_shortsin_port;

structin_addrsin_addr;

charsin_sero[8];

}

就包含了需要建立连接的本地的地址,包括地址族、IP和端口信息。

sin_family字段必须把它设为AF_INET,这是告诉WinSock使用的是IP地址族。

sin_port就是要用来通讯的端口号。

sin_addr就是要用来通讯的IP地址信息。

在这里,必须还得提一下有关'

大头(big-endian)'

小头(little-endian)'

因为各种不同的计算机处理数据时的方法是不一样的,IntelX86处理器上是用'

小头'

形式来表示多字节的编号,就是把低字节放在前面,把高字节放在后面,而互联网标准却正好相反,所以,必须把主机字节转换成网络字节的顺序。

WinSockAPI提供了几个函数。

把主机字节转化成网络字节的函数;

u_longhtonl(u_longhostlong);

u_shorthtons(u_shorthostshort);

把网络字节转化成主机字节的函数;

u_longntohl(u_longnetlong);

u_shortntohs(u_shortnetshort);

这样,设置IP地址和port端口时,就必须把主机字节转化成网络字节后,才能用Bind()函数来绑定套接字和地址。

当绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。

intlisten(SOCKETs,intbacklog);

这个函数可以把套接字转成监听模式。

如果客户端有了连接请求,我们还必须使用

intaccept(SOCKETs,structsockaddrFAR*addr,intFAR*addrlen);

来接受客户端的请求。

现在基本上已经完成了一个服务器的建立,而客户端的建立的流程则是初始化WinSock,然后创建Socket套接字,再使用

intconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);

来连接服务端。

下面是一个最简单的创建服务器端和客户端的例子:

服务器端的创建:

WSADATAwsd;

SOCKETsListen;

SOCKETsclient;

UINTport=800;

intiAddrSize;

structsockaddr_inlocal,client;

WSAStartup(0x11,&

wsd);

sListen=Socket(AF_INET,SOCK_STREAM,IPPOTO_IP);

local.sin_family=AF_INET;

local.sin_addr=htonl(INADDR_ANY);

local.sin_port=htons(port);

bind(sListen,(structsockaddr*)&

local,sizeof(local));

listen(sListen,5);

sClient=accept(sListen,(structsockaddr*)&

client,&

iAddrSize);

客户端的创建:

SOCKETsClient;

charszIp[]="

127.0.0.1"

;

structsockaddr_inserver;

sClient=Socket(AF_INET,SOCK_STREAM,IPPOTO_IP);

server.sin_family=AF_INET;

server.sin_addr=inet_addr(szIp);

server.sin_port=htons(port);

connect(sClient,(structsockaddr*)&

server,sizeof(server));

当服务器端和客户端建立连接以后,无论是客户端,还是服务器端都可以使用

intsend(SOCKETs,constcharFAR*buf,intlen,intflags);

intrecv(SOCKETs,charFAR*buf,intlen,intflags);

函数来接收和发送数据,因为,TCP连接是双向的。

当要关闭通讯连接的时候,任何一方都可以调用

intshutdown(SOCKETs,inthow);

来关闭套接字的指定功能,再调用

intcloseSocket(SOCKETs);

来关闭套接字句柄,这样一个通讯过程就算完成了。

计算机网络(第5版)280页图6-32所示的系统调用使用顺序:

注意:

上面的代码没有任何检查函数返回值,如果你作网络编程就一定要检查任何一个WinSockAPI函数的调用结果,因为很多时候函数调用并不一定成功。

上面介绍的函数,返回值类型是int的话,如果函数调用失败的话,返回的都是SOCKET_ERROR。

4.VC中socket编程步骤

sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);

基于TCP的socket编程是采用的流式套接字。

在这个程序中,将两个工程添加到一个工作区。

要链接一个ws2_32.lib的库文件。

服务器端编程的步骤:

1:

加载套接字库,创建套接字(WSAStartup()/socket());

2:

绑定套接字到一个IP地址和一个端口上(bind());

3:

将套接字设置为监听模式等待连接请求(listen());

4:

请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());

5:

用返回的套接字和客户端进行通信(send()/recv());

6:

返回,等待另一连接请求;

7:

关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。

服务器端代码如下:

#include<

stdio.h>

Winsock2.h>

voidmain()

{

WORDwVersionRequested;

WSADATAwsaData;

interr;

wVersionRequested=MAKEWORD(1,1);

err=WSAStartup(wVersionRequested,&

wsaData);

if(err!

=0){

return;

}

if(LOBYTE(wsaData.wVersion)!

=1||HIBYTE(wsaData.wVersion)!

=1){

WSACleanup();

SOCKETsockSrv=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_INaddrSrv;

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&

addrSrv,sizeof(SOCKADDR));

listen(sockSrv,5);

SOCKADDR_INaddrClient;

intlen=sizeof(SOCKADDR);

while

(1){

SOCKETsockConn=accept(sockSrv,(SOCKADDR*)&

addrClient,&

len);

charsendBuf[50];

sprintf(sendBuf,"

Welcome%stohere!

"

inet_ntoa(addrClient.sin_addr));

send(sockConn,sendBuf,strlen(sendBuf)+1,0);

charrecvBuf[50];

recv(sockConn,recvBuf,50,0);

printf("

%s\n"

recvBuf);

closesocket(sockConn);

客户端编程的步骤:

向服务器发出连接请求(connect());

和服务器端进行通信(send()/recv());

客户端的代码如下:

SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0);

addrSrv.sin_addr.S_un.S_addr=inet_addr("

);

connect(sockClient,(SOCKADDR*)&

send(sockClient,"

hello"

strlen("

)+1,0);

charrecvBuf[50];

recv(sockClient,recvBuf,50,0);

printf("

closesocket(sockClient);

WSACleanup();

附录2、PING源代码

//PING.H

#defineWIN32_LEAN_AND_MEAN

windows.h>

winsock2.h>

ws2tcpip.h>

stdlib.h>

typedefstructtagIP_HEADER{

unsignedinth_len:

4;

//lengthofheader(4b)

unsignedintver:

//version(4b)

unsignedchartos;

//tos(1B)

unsignedshorttotal_len;

//totallength(2B)

unsignedshortident;

//identification(2B)

unsignedshortfrag_flags;

//fragandflags(2B)

unsignedcharttl;

//timeoflives(1B)

unsignedcharprotocol;

//protocol(1B)

unsignedshortchecksum;

//checksum(2B)

unsignedintsourceip;

//sourceip(4B)

unsignedintdestip;

//destinationip(4B)

}IP_HEADER,*PIP_HEADER;

//lengthoftotal(20B)

typedefstructtagIP_OPT_HEADER{

unsignedcharcode;

//optiontype(1B)

unsignedcharlen;

//lengthofoptionheader(1B)

unsignedcharptr;

//下一个可存放地址的位置(1B)

unsignedlongaddr[9];

//listofipaddress(4B/d)

}IP_OPT_HEADER,*PIP_OPT_HEADER;

//lengthoftotal(39B)

typedefstructtagICMP_HEADER{

unsignedchartype;

//icmptype(1B)

//codeoftype(1B)

unsignedshortid;

//identification(2B)

unsignedshortseq;

//sequence(2B)

unsignedlongtimestamp;

//(2B)

//thisisnotstandardheader,butwereservespacefortime

}ICMP_HEADER,*PICMP_HEADER;

//totallength(10B)

#defineDEF_PACKET_SIZE32

#defineMAX_PACKET_SIZE1024

#defineICMP_ECHO8

#defineICMP_ECHOREPLY0

#defineIP_RECORD_ROUTER7

voidusageinfo(char*progname);

voidFillIcmpData(char*icmp_data,intsize);

USHORTCheckSum(USHORT*buf,intsize);

voidDecodeIcmpHeade

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学研究 > 教学计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1