文档库 最新最全的文档下载
当前位置:文档库 › 网络编程课程设计

网络编程课程设计

网络编程课程设计
网络编程课程设计

网络编程

课程设计说明书

基于TCP/IP的网络文字聊天程序设计

专业:网络工程

班级:网络7878

姓名:周岐就

学号:6554773546

时间:2016.12.18

摘要

Socket 接口是TCP/ IP 网络的API(应用程序接口) ,Windows Sockets (Winsock) 是一个基于Socket 模型的API。本文通过论述了Windows 环境下的实现计算机数据传输服务的机制,

TCP/ IP 协议的体系结构、组成与功能以及通过TCP/ IP 协议实现异构型网络互连的机理。对TCP/ IP 协议提供的两种通信功能进行了分析,辩证地提出了它们不同的应用场合。本聊天工具使用VC++语言和较成熟的微软的mfc71作为开发语言

细设计的整个开发过程进行全面论述。最后,给出了在TCP/ IP 基础上开发通信应用程序的编程模型和实现要点,对用户开发应用程序有一定参考意义。

关键词: 网络;TCP/ IP 协议通信编程VC++

引言

Internet C语言或是web网络语言进行设计。Internet上数据传输协议主要有TCP和UDP。TCP是有连接协议它要求计算机进行对话时必须先建立连接。保证数据传送安全到达目的地。UDP 是无连接协议。它只是将信息送到网络上并不检查数据是否到达了目的地。要进行实时会话。则应该采用TCP协议。本程序采用的协议就是TCP协议。传输控制协议TCP (Transmission Control Protocol) 是Internet 最基本的网络通信协议, 它由一系列协议组成,其中核心协议是传输层的TCP和UDP( User Datagram Protocol, 用户数据报协议)协议。TCP 协议属于“面向连接,可靠传输”的型, 面向连接的传输意味着在进行通信以前, 需要在两个系统之间建立逻辑连接, 在每个数据传输的过程中都需要进行应答以保证数据包的完整, 这种方法可以保证数据传输的可靠性,UDP 协议属于“面向无连接, 不可靠传输”的类型, 该协议只负责接收和传送上层协议传递的消息, 它本身不做任何的检测、修改与应答, 网络开销一般要小于TCP协议。在优良的网络环境, UDP 的工作效率较TCP 协议要高。在Windows 环境下开发网络应用程序, 通常都是使用Microsoft的网络编程接口, 即Windows 套接字Windows Socket( 简称Winsock), 它包含在Winsock.dll 中的一组API 中,用于在网络上传输数据和交换信息, 编程人员需要熟悉和掌握相关的网络协议、系统的底层知识以及网络软硬件技术, 因而Winsock 编程相当复杂。所幸的是, MFC的CSocket类对WinSock 进行了有效的封装, 并不需要直接与Winsock 的API 打交道, 调用CSocket Winsock 的访问大大简化。

目录

摘要 (1)

引言 (2)

一、课程设计任务书 (4)

(一)设计题目 (4)

(二)设计要求 (4)

二、设计原理及Socket套接字 (5)

(一)设计原理 (5)

(二)Socket套接字 (5)

三、TCP/IP协议 (7)

(一)网络接口层 (7)

(二)网络层 (7)

(三)传输层 (8)

(四)应用层 (8)

(五)TCP/IP协议运作机制 (8)

(六)通讯端口 (10)

(七)IP地址 (10)

四、课程设计内容 (11)

(一)设计功能 (11)

(二)流程图 (11)

五、程序创建过程 (12)

(一)创建服务器 (12)

(二)创建客户端 (14)

六、程序截图 (17)

(一)服务器界面截图 (17)

(二)客户端界面截图 (18)

七、设计使用说明 (19)

八、课程设计总结 (20)

参考文献 (22)

一、课程设计任务书

(一)设计题目

基于TCP/IP的网络文字聊天程序设计。

(二)设计要求

1、开发平台:Visual C++ 6.0

2、对设计方法的要求

使用Visual C++ 6.0开发出在Windows控制台或图形界面下运行的程序。

3、对设计内容的要求

①实现网络文字聊天程序的服务器端。

②实现网络文字聊天程序的客户端。

③主程序的结构和流程。

④程序运行过程的截图。

⑤网络文字聊天程序的实现原理。

⑥网络文字聊天程序实现代码的分析。

4、对课程设计说明书的要求

①设计思路与开发过程。

②对主要代码段要有较详细的注释。

③对本次设计的评价、设计的收获与建议。

二、设计原理及Socket套接字

(一)设计原理

计算机网络技术发展至今已经大大超越了人们当初的预想,无论是人们日常的工作还是学习,我们都越来越多的依靠到互联网。各种实时性的聊天娱乐软件也同时诞生,而且为我们的即时通讯带来了众多的方便,比如说大家所熟知的腾讯QQ、微软的MSN、移动的Fetion等,都是做的比较成功的实时聊天工具。随着网络的日益普及,各种聊天工具也层出不穷,但当我们学习了《网络编程》这门课程之后,我们便会觉得,其实要实现简单的网络通讯其实并不难。接下来的课程设计就是针对一个简单的网络聊天程序,利用MFC为开发工具,实现基本的通讯功能。

此程序主要分为两部分:服务器端和客户端。服务器端用于提供一个网络端口,等待客户端发出请求,登录到此服务端,然后进行网络通讯和消息的转发;客户端可通过服务器端的IP地址发送连接请求,然后登陆聊天室。整个程序的主体使用了CSocket类的方法,实现了网络通讯聊天。

整个程序设计为两个部分:服务器(Server)和客户端(Client)。

多人聊天的关键在于要将每个客户端发送过来的消息分发给所有其他客户端,为了解决这个问题,在服务器程序中建立一个套接口链表,用来保存所有与客户端建立了连接的服务端口。下面描述了多人聊天的实现原理:当客户端Client N向对应的服务端口N发送了消息Message,服务端口N 将Message复制给所有套接口列表(USERLIST)中的套接口缓冲区,然后向每个服务端口发送WRITE消息,使每个服务端口将Message发送给对应的客户端。这样,所有客户端就都获得了Message消息,实现了多人聊天功能。

(二)Socket套接字

socket的英文原义是“孔”或“插座”。在这里作为4BDS UNIX的进程通信机制,取后一种意思。socket非常类似于电话插座。以一个国家级电话网为例。电话的通话双方相当于相互通信的2个进程,区号是它的网络地址;区内一个单位的交换机相当于一台主机,主机分配给每个用户的局内号码相当于socket号。任何用户在通话之前,首先要占有一部电话机,相当于申请一个socket;同时要知道对方的号码,相当于对方有一个固定的socket。然后向对方拨号呼叫,相当于发出连接请求(假如对方不在同一区内,还要拨对方区号,相当于给出网络地址)。对方假如在场并空闲(相当于通信的另一主机开机且可以接受连接请求),拿起电话话筒,双方就可以正式通话,相当于连接成功。双方通话的过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向socket发送数据和

从socket接收数据。通话结束后,一方挂起电话机相当于关闭socket,撤消连接。

在电话系统中,一般用户只能感受到本地电话机和对方电话号码的存在,建立通话的过程,话音传输的过程以及整个电话系统的技术细节对他都是透明的,这也与socket机制非常相似。socket利用网间网通信设施实现进程通信,但它对通信设施的细节毫不关心,只要通信设施能提供足够的通信能力,它就满足了。

至此,我们对socket进行了直观的描述。抽象出来,socket实质上提供了进程通信的端点。进程通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的。正如打电话之前,双方必须各自拥有一台电话机一样。在网间网内部,每一个socket用一个半相关描述:

(协议,本地地址,本地端口)

一个完整的socket有一个本地唯一的socket号,由操作系统分配。

最重要的是,socket 是面向客户/服务器模型而设计的,针对客户和务器程序提供不同的socket 系统调用。客户随机申请一个socket (相当于一个想打电话的人可以在任何一台入网电话上拨号呼叫),系统为之分配一个socket号;服务器拥有全局公认的socket ,任何客户都可以向它发连接请求和信息请求(相当于一个被呼叫的电话拥有一个呼叫方知道的电号码)。

三、TCP/IP协议

TCP/IP模型也被称作DoD模型(Department of Defense Model)。TCP/IP字面上代表了两个协议:TCP(传输控制协议)和IP(网际协议)。

从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层、网络层、传输层、应用层。如一图所示:

图一TCP/IP协议

(一)网络接口层

物理层是定义物理介质的各种特性:

1、机械特性;

2、电子特性;

3、功能特性;

数据链路层是负责接收IP数据包并通过网络发送,或者从网络上接收物理帧,抽出IP数据包,交给IP层。

常见的接口层协议有:

Ethernet 802.3、Token Ring 802.5、X.25、Frame relay、HDLC、PPP ATM等。(二)网络层

负责相邻计算机之间的通信。其功能包括三方面。

一、处理来自传输层的分组发送请求,收到请求后,将分组装入IP数据报,填充报头,选择去往信宿机的路径,然后将数据报发往适当的网络接口。

二、处理输入数据报:首先检查其合法性,然后进行寻径--假如该数据报已到达信宿机,则去掉报头,将剩下部分交给适当的传输协议;假如该数据报尚未到达信宿,则转发该数据报。

三、处理路径、流控、拥塞等问题。

网络层包括:IP(Internet Protocol)协议、ICMP(Internet Control Message Protocol)控制报文协议、ARP(Address Resolution Protocol)地址转换协议、RARP(Reverse ARP)反向地址转换协议。IP是网络层的核心,通过路由选择将下一条IP封装后交给接口层。IP数据报是无连接服务。ICMP是网络层的补充,可以回送报文。用来检测网络是否通畅。Ping命令就是发送ICMP的echo包,通过回送的echo relay进行网络测试。ARP是正向地址解析协议,通过已知的IP,寻找对应主机的MAC地址。RARP是反向地址解析协议,通过MAC地址确定IP地址。比如无盘工作站还有DHCP服务。

(三)传输层

提供应用程序间的通信。其功能包括:一、格式化信息流;二、提供可靠传输。为实现后者,传输层协议规定接收端必须发回确认,并且假如分组丢失,必须重新发送,即耳熟能详的"三次握手"过程,从而提供可靠的数据传输。传输层协议主要是:传输控制协议TCP(Transmission Control Protocol)和用户数据报协议UDP(User Datagram protocol)。

(四)应用层

向用户提供一组常用的应用程序,比如电子邮件、文件传输访问、远程登录等。远程登录TELNET使用TELNET协议提供在网络其它主机上注册的接口。TELNET会话提供了基于字符的虚拟终端。文件传输访问FTP使用FTP协议来提供网络内机器间的文件拷贝功能。应用层协议主要包括如下几个:FTP、TELNET、DNS、SMTP、RIP、NFS、HTTP。FTP(File Transfer Protocol)是文件传输协议,一般上传下载用FTP服务,数据端口是20H,控制端口是21H。Telnet 服务是用户远程登录服务,使用23H端口,使用明码传送,保密性差、简单方便。DNS(Domain Name Service)是域名解析服务,提供域名到IP地址之间的转换。SMTP(Simple Mail Transfer Protocol)是简单邮件传输协议,用来控制信件的发送、中转。RIP (Router Information Protocol)是路由信息协议,用于网络设备之间交换路由信息。NFS (Network File System)是网络文件系统,用于网络中不同主机间的文件共享。HTTP(Hypertext Transfer Protocol)是超文本传输协议,用于实现互联网中的WWW服务。

(五)TCP/IP协议运作机制

1.IP:IP层接收由更低层(网络接口层例如以太网设备驱动程序)发来的数据包,并把该数据包发送到更高层---TCP或UDP层;相反,IP层也把从TCP或UDP

层接收来的数据包传送到更低层。IP数据包是不可靠的,因为IP并没有做任何事情来确认数据包是按顺序发送的或者没有被破坏。IP数据包中含有发送它的主机的地址(源地址)和接收它的主机的地址(目的地址)。

高层的TCP和UDP服务在接收数据包时,通常假设包中的源地址是有效的。也可以这样说,IP地址形成了许多服务的认证基础,这些服务相信数据包是从一个有效的主机发送来的。IP确认包含一个选项,叫作IP source routing,可以用来指定一条源地址和目的地址之间的直接路径。对于一些TCP和UDP的服务来说,使用了该选项的IP包好像是从路径上的最后一个系统传递过来的,而不是来自于它的真实地点。这个选项是为了测试而存在的,说明了它可以被用来欺骗系统来进行平常是被禁止的连接。那么,许多依靠IP源地址做确认的服务将产生问题并且会被非法入侵。

2.TCP:TCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的所以只能用于点对点的通讯。

TCP提供的是一种可靠的数据流服务,采用"带重传的肯定确认"技术来实现传输的可靠性。TCP还采用一种称为"滑动窗口"的方式进行流量控制,所谓窗口实际表示接收能力,用以限制发送方的发送速度。

如果IP数据包中有已经封好的TCP数据包,那么IP将把它们向'上'传送到TCP层。TCP将包排序并进行错误检查,同时实现虚电路间的连接。TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。

TCP将它的信息送到更高层的应用程序,例如Telnet的服务程序和客户程序。应用程序轮流将信息送回TCP层,TCP层便将它们向下传送到IP层,设备驱动程序和物理介质,最后到接收方。

面向连接的服务(例如Telnet、FTP、rlogin、X Windows和SMTP)需要高度的可靠性,所以它们使用了TCP。DNS在某些情况下使用TCP(发送和接收域名数据库),但使用UDP传送有关单个主机的信息。

3.UDP:UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。

UDP通讯时不需要接收方确认,属于不可靠的传输,可能会出丢包现象,实际应用中要求在程序员编程验证。

UDP与TCP位于同一层,但它不管数据包的顺序、错误或重发。因此,UDP 不被应用于那些使用虚电路的面向连接的服务,UDP主要用于那些面向查询---应答的服务,例如NFS。相对于FTP或Telnet,这些服务需要交换的信息量较小。使用UDP的服务包括NTP(网络时间协议)和DNS(DNS也使用TCP)。

欺骗UDP包比欺骗TCP包更容易,因为UDP没有建立初始化连接(也可以称为握手)(因为在两个系统间没有虚电路),也就是说,与UDP相关的服务面临着更大的危险。

4.ICMP:ICMP与IP位于同一层,它被用来传送IP的的控制信息。它主要是用来提供有关通向目的地址的路径信息。ICMP的'Redirect'信息通知主机通向其他系统的更准确的路径,而'Unreachable'信息则指出路径有问题。另外,如果路径不可用了,ICMP可以使TCP连接'体面地'终止。PING是最常用的基于ICMP 的服务。

(六)通讯端口

TCP和UDP服务通常有一个客户/服务器的关系,例如,一个Telnet服务进程开始在系统上处于空闲状态,等待着连接。用户使用Telnet客户程序与服务进程建立一个连接。客户程序向服务进程写入信息,服务进程读出信息并发出响应,客户程序读出响应并向用户报告。因而,这个连接是双工的,可以用来进行读写。

两个系统间的多重Telnet连接是如何相互确认并协调一致呢?TCP或UDP 连接唯一地使用每个信息中的如下四项进行确认:

源IP地址发送包的IP地址。

目的IP地址接收包的IP地址。

源端口源系统上的连接的端口。

目的端口目的系统上的连接的端口。

端口是一个软件结构,被客户程序或服务进程用来发送和接收信息。一个端口对应一个16比特的数。服务进程通常使用一个固定的端口,例如,SMTP使用25、Xwindows使用6000。这些端口号是'广为人知'的,因为在建立与特定的主机或服务的连接时,需要这些地址和目的地址进行通讯。

(七)IP地址

在Internet上连接的所有计算机,从大型机到微型计算机都是以独立的身份出现,我们称它为主机。为了实现各主机间的通信,每台主机都必须有一个唯一的网络地址。就好像每一个住宅都有唯一的门牌一样,才不至于在传输资料时出现混乱。

Internet的网络地址是指连入Internet网络的计算机的地址编号。所以,在Internet网络中,网络地址唯一地标识一台计算机。

我们都已经知道,Internet是由几千万台计算机互相连接而成的。而我们要确认网络上的每一台计算机,靠的就是能唯一标识该计算机的网络地址,这个地址就叫做IP(Internet Protocol的简写)地址,即用Internet协议语言表示的地址。

目前,在Internet里,IP地址是一个32位的二进制地址,为了便于记忆,将它们分为4组,每组8位,由小数点分开,用四个字节来表示,而且,用点分开的每个字节的数值范围是0~255,如202.116.0.1,这种书写方法叫做点数表示法。

四、课程设计内容

(一)设计功能

实现网络文字聊天程序的基本功能。主要包括:

1. TCP 聊天服务器程序

2. TCP 聊天客户端程序

(二)流程图

1. 服务器流程图

·

图二 服务器流程图

开始 判断输入端口号是否可用 输入端口号 启动服务器 创建不成功 创建成功 结束 是 否

2. 客户端流程图

图三 客户端流程图

开始 是否连接成功

结束 运行客户端 连接服务器 重新连接 进入聊天室 输入文字 发送消息

否 是

五、程序创建过程

(一)创建服务器

1、创建一个基于对话框的应用程序,工程名为Server

2、在类CServerAPP中InitInstance方法中初始化套接字。代码如下:

WSADATA wsd;

AfxSocketInit(&wsd);

3、从CSocket类中派生出CClientSocket类,在该类中定义成员变量m_pDlg,代码如下:

protected:

CServerDlg* m_pDlg;

4、向CServerSocket类中添加SetDialog函数,为m_pDlg成员变量赋值。代码如下:

void CServerSocket::SetDialog(CServerDlg* pDialog)

{

m_pDlg = pDialog;

}

5、改写CServerSocket类中的OnAccept方法,在套接字有连接请求时接受其连接。代码如下:

void CServerSocket::OnAccept(int nErrorCode)

{

CSocket::OnAccept(nErrorCode);

if (m_pDlg)

m_pDlg->AcceptConnect();

}

6、从CSocket类再次派生一个新类CClientSocket,在该类中定义成员变量m_pDlg。代码如下:

protected:

CServerDlg* m_pDlg;

7、向CClientSocket类中添加SetDialog函数,为m_pDlg成员变量赋值。代码如下:

void CClientSocket::SetDialog(CServerDlg* pDialog)

{

m_pDlg = pDialog;

}

8、改写CServerSocket类中的OnReceive方法,在套接字有数据接收时接收

数据。代码如下:

void CClientSocket::OnReceive(int nErrorCode)

{

CSocket::OnReceive(nErrorCode);

if(m_pDlg)

{

m_pDlg->ReceiveData(*this);

}

}

9、在对话框类中添加如下成员变量:

CPtrList m_socketlist;

CServerSocket m_ServerSock;

10、向对话框类中添加AcceptConnect方法,接受客户端的连接。代码如下:

void CServerDlg::AcceptConnect()

{

CClientSocket* psocket = new CClientSocket();

psocket->SetDialog(this);

if (m_ServerSock.Accept(*psocket))

m_socketlist.AddTail(psocket);

else

delete psocket;

}

11、向对话框类中添加ReceiveData方法,用于接收套接字数据。代码如下:

void CServerDlg::ReceiveData(CSocket &socket)

{

char bufferdata[BUFFERSIZE];

int len = socket.Receive(bufferdata,BUFFERSIZE);

if (len != -1)

{

bufferdata[len] = 0;

POSITION pos = m_socketlist.GetHeadPosition();

while (pos != NULL)

{

CClientSocket* socket =

(CClientSocket*)m_socketlist.GetNext(pos);

if (socket != NULL)

socket->Send(bufferdata,len);

}

}

}

12、处理“设置”按钮的单击事件,创建并开始监听套接字。代码如下:

void CServerDlg::OnConfig()

{

m_ServerSock.SetDialog(this);

CString strPort,strIP;

m_ServerPort.GetWindowText(strPort);

m_ServerIP.GetWindowText(strIP);

if (!strPort.IsEmpty() && !strIP.IsEmpty())

{

UINT port = atoi(strPort);

m_ServerSock.Create(port,SOCK_STREAM,strIP);

BOOL ret = m_ServerSock.Listen();

if (ret)

MessageBox("设置成功!","提示");

}

}

(二)创建客户端

1、创建一个基于对话框的应用程序,工程名为Client

2、在类CClientApp中InitInstance方法中初始化套接字。代码如下:

WSADATA wsd;

WSAStartup(MAKEWORD(2,2),&wsd);

3、从CSocket类中派生出CClientSocket类,在该类中添加m_pDialog成员。代码如下:

protected:

CClientDlg *m_pDialog;

4、在CClientSocket中添加SetDialog方法,用于设置成员变量。代码如下:

void CClientSocket::SetDialog(CClientDlg *pDialog)

{

m_pDialog = pDialog;

}

5、改写CClientSocket类中的OnReceive旭方法,在套接字有数据接收时调用该方法。代码如下:

void CClientSocket::OnReceive(int nErrorCode)

{

CSocket::OnReceive(nErrorCode);

if (m_pDialog != NULL)

m_pDialog->ReceiveText();

}

6、在对话框类中添加如下成员变量:

CClientSocket m_SockClient;

CString m_Name;

7、在对话框类中添加ReceiveText方法接收数据。代码如下:void CClientDlg::ReceiveText()

{

char buffer[BUFFERSIZE];

int len = m_SockClient.Receive(buffer,BUFFERSIZE);

if (len != -1)

{

buffer[len] = '\0';

m_List.AddString(buffer);

}

}

8、在对话框初始化时创建套接字。代码如下:

m_SockClient.Create();

m_SockClient.SetDialog(this);

9、处理“登录”按钮的单击事件,开始登录服务器。代码如下:void CClientDlg::OnLogin()

{

CString strIP,strPort;

UINT port ;

m_ServerIP.GetWindowText(strIP);

m_NickName.GetWindowText(m_Name);

m_ServerPort.GetWindowText(strPort);

if (strIP.IsEmpty() || strPort.IsEmpty() || m_Name.IsEmpty())

{

MessageBox("请设置服务器信息","提示");

return;

}

port = atoi(strPort);

if (m_SockClient.Connect(strIP,port))

{

MessageBox("连接服务器成功!","提示");

CString str;

str.Format("%s----->%s",m_Name,"进入聊天室");

m_SockClient.Send(str.GetBuffer(0),str.GetLength());

}

else

{

MessageBox("连接服务器失败!","提示");

}

}

10、处理“发送”按钮的单击事件,向服务器发送数据,再由服务器转发这些数据。代码如下:

void CClientDlg::OnSendText()

{

CString strText,strInfo;

m_Text.GetWindowText(strText);

if (!strText.IsEmpty() && !m_Name.IsEmpty())

{

strInfo.Format("%s说: %s",m_Name,strText);

int len =

m_SockClient.Send(strInfo.GetBuffer(strInfo.GetLength()),strInfo.GetLength());

}

}

六、程序截图

(一)服务器界面截图

图四设置服务器

图五建立服务器端

(二)客户端界面截图

图六设置客户端

图七建立连接

相关文档