【VB开源代码栏目提醒】:网学会员--在 VB开源代码编辑为广大网友搜集整理了:netbios实现一个类似qq的通信程序——客户端5 - 学士论文绩等信息,祝愿广大网友取得需要的信息,参考学习。
网络工程实验
报告设计题目: netbios 实现一个类似 qq 的通信程序——客户端 92 学号: 一个类似 qq 的
通信程序——客户端1.1 设计目的 1、进一步掌握利用 Visual C进行程序设计的能力; 2、进一步理解和运用面向对象程序设计的思想和方法; 3、初步掌握开发一个小型实用系统的基本方法; 4、学会调试一个较长程序的基本方法; 5、理解 Windows 程序的运行过程; 6、掌握 netbios 编程方法。
1.2 设计内容 本实验设计内容是:设计一个程序,实现聊天功能,要求有客户端和服务器端。
客户端能实现消息的输入和发送、接收消息、连接服务器与断开连接等基本功能;服务器端要求能收发信息、保存客户端的 IP 信息地址、将接收到的消息向所有客户端转发等基本信息。
1.3 设计要求 整个程序使用 netbios 函数做网络数据收发,基于 UDP 协议。
可以直接使用 Windows API编程(SDK 编程),也可以使用 MFC 编程。
本
课程设计中我们使用的是 MFC 编程。
其具体的设计要求如下所述:1、服务器端: 在服务器端,当服务器端程序运行时便初始化 socket 创建服务器端,在服务器端包含一个发送窗口和一个接收窗口,以及一个 ListBox 来显示当前连接到服务器上的客户端的IP 地址。
服务器端功能: 1、初始化 netbios 创建服务器端。
2、接受用户传送来的连接判断命令,并向用户发出响应命令。
2 3、维护一个链表,保存所有用户的 IP 地址。
显示所有在线 IP。
4、向链表中的所有用户发送系统消息。
5、接受用户传送来的聊天信息,然后向链表中的所用用户转发。
2、客户端: 客户端界面,有一个用于显示接受的聊天信息,和一个用来接受用户输入的聊天信息。
当按下“发送”按钮时将信息发送给服务器。
程序运行后用户先输入自己呢称然后进行连接,如果成功则在接收窗口输出成功提示,否则弹出连接失败警告框。
在连接好之后用户也可以选择与服务器断开。
32 设计环境或器材、原理与说明2.1 设计环境与器材因为选择使用 MFC 编程,该程序又是网络编程,所以设计环境与器材为:PC 机两到三台程序试运行时需要多台电脑充当客户端;能正常连接的网卡;Windows 环境与 Microsoft Visual C 6.0 编译环境;2.2 原理与说明 在
计算机网络中,信息的传输是建立在物理传输介质与网络传输协议上的,TCP/IP 协议是
网络协议的一种,它分为不同的层次:TCPTrans
mission Control Protocol——传输控制协议,UDPUser Datagram Protocol——用户数据报协议;IPInternet Protocol——网际协议;它们分别
工作于传输层与网络层。
Window Socket 是 Windows 下的标准网络程序设计接口,它是由一些 API 函数组成,用以提供对网络通信的支持。
该程序设计使用 Windows Sockets 编程。
在数据传输协议中,我们使用 UDP 协议,UDP协议是无连接的协议,在服务器端不调用 listen 函数进行监听,也不调用 accept 函数建立连接, 其操作流程图如下图所示: 服务器端 客户端 socket函数建立套接字 函数建立套接字 socket bind bind 函数给套接字指定本地地址 函数给套接字指定本地地址 send 函数和 reve send 函数和 reve 函数收发数据 函数收发数据 closesocket函数关闭套接字 osesocket函数关闭套接字 cl 图 2-1 无连接协议的套接字操作流程图首先,用 socket 函数建立套接字,然后根据本地的 IP 进行绑定,然后就可以通过使用 send函数和 reve 函数来进行数据的发送和接收了。
43 设计过程及程序
代码3.1 服务器端设计3.1.1 服务器端
程序流程设计 下图是服务器端的程序流程
设计图,当程序开始运行时,便初始 netbios 环境。
初始化完成后,程序便等待客户端的接入和等待接收信息。
如果客户端发起请求连接的 connect请求,便将该客户端的 IP 加如链表,并在 ListBox 中显示出来;如果收到的是已经建立好连接的客户端发来的消息信息,则遍历链表,将收到的消息向链表中所保存的所有的客户端发送并在服务器端的接收窗口显示该消息;如果收到客户端发送来的断开连接请求,则在 ListBox 和链表中删除该客户端的 IP。
关闭窗口程序结束。
开始 初始化WinSock环 境 等待接收信息 disconnect connect connect disconnect 接收信息是否为 连接信息 在链表和ListBox 遍历链表向链表中所有 在链表和ListBox 中删除对应IP 的用户转发信息 中添加对应IP 在接收窗口显 示信息 图 3-1 服务器端程序设计3.1.2 服务器端界面设计 使用 MFC 可以很方便的建立对话框,在打开 Microsoft Visual C 6.0 后建立一个 MFCAppWizardexe工程,然后在选择类型对话框中选择 Dialog Based,在选择包含部分时选择Windows Sockets,然后点击完成,于是便有了一个基本的对话框。
我们可以通过 MFC 中 5提供的编辑工具在该对话框中进行设计,如添加文本框、按钮、静态文本框、ListBox 等。
然后根据需要对各个控件的属性等进行设定,下图是根据客户端功能需求所设计的客户端界面: 图 3-2 客户端界面设计当有客户端连入后,客户端的 IP 会自动的显示在“在线主机
列表”下的 ListBox 中,其下面的删除按钮可以将 ListBox 中所选的 IP 删除;所有客户端发来的消息和服务器自己所发的消息都在接收窗口中显示,并可通过清除内容按钮清除内容;服务器端也可以向所有客户端发送
系统消息,该功能通过发送窗口和右边的发送、清除按钮实现。
3.1.3 服务器端套接字的具体操作 该程序设计使用 UDP 无连接的用户数据报协议,所以在设计中我们不调用 listen 函数进行监听,也不调用 accept 函数建立连接,其操作流程可见图 3-1。
下面是在程序设计中建立套接字、绑定的具体实现: // socket 函数建立套接字 WSAStartupMAKEWORD2 0 ampm_WSAData //初始化套接字 m_sockLocal socketAF_INET SOCK_DGRAM 0 //创建本地服务套接字 //选择程序要处理的网络事件:WM_SOCKET 和 FD_READ WSAAsyncSelectm_sockLocal GetSafeHwnd WM_SOCKET FD_READ m_addr_in.sin_addr.S_un.S_addr inet_addrquot172.17.50.35quot //指定 IP 地址服务器所在系统 IP 地址 m_addr_in.sin_family AF_INET //协议族 m_addr_in.sin_port htonsSERVER_PORT //服务器端口号 bindm_sockLocal SOCKADDRampm_addr_in sizeofm_addr_in // bind 函数给套接字指定本地地址下面分别是接收和发送数据的具体
代码: recvfromm_sockLocal buf 1024 0 SOCKADDRampm_addrfrom ampm_fromlen sendtom_sockLocal buf 1024 0 SOCKADDRampm_addrfrom sizeofm_addrfrom 63.1.4 链表的维护以及消息的广播 在该程序的服务器端设计了一个链表,用来保存所有在线的客户端的 IP 地址。
当服务器端收到客户端发送来的连接请求消息时,便把该客户端的 IP 加人到建立的链表中去,在广播消息的时候可以通过遍历该链表将消息发送给每一个客户端。
下面分别是建立链表、遍历链表、增加删除链表的具体实现
代码: //定义一个用来保存 IP 的链表 listltCStringgt IPlist listltCStringgt::iterator iter //对链表的增加、删除 IPlist.push_backIP IPlist.removeIP // 遍历链表以广播接收到的客户消息 for iter IPlist.begin iter IPlist.end iter //从链表的开始结点到结束结点 IP iter m_addrfrom.sin_addr.s_addrinet_addrIP sendtom_sockLocal buf 1024 0 SOCKADDRampm_addrfrom sizeofm_addrfrom 3.1.5 连接请求与断开连接 当客户端开启并发出连接信息时,在服务器端判断,如果是连接请求信息“connect”则如上一节所述将其 IP 加入链表同时加入 ListBox 显示出来,并向客户端发送连接成功的确认信息。
如果服务器端将某个 IP 从链表中删除,也需要给客户端发送一个断开连接提示信息。
若是客户端选则了断开连接,则当服务器端收到相应的断开信息后就将链表中对应的 IP 删除。
3.2 客户端的设计3.2.1 客户器端程序流程设计 下图为客户端的程序流程图,和服务器相同程序一开始便使用 socket 函数建立套接字初始化 netbios环境。
然后输入服务器端的 IP 地址并发起连接请求,如果连接超时则返回输入 IP 状态,若成功则可发送和接收消息,在此过程中如果服务器将本客户端断开,则返回输入 IP 态。
若客户端自己选择与服务器断开,则向服务器发送断开信息并返回到输入 IP 7状态继续循环,知道关闭窗口。
开始 初始化WinSock环境 输入服务器IP地址等 发送连接信息并等待回应 N 是否连接成功? Y 消息发送和接收 Y N 是否为断开 消息? 图 3-3 客户端程序流程图3.2.2 客户端界面设计 与服务器端的界面设计相同,只需根据需求设计出相应的控件,客户端界面设计如下图所示: 图 3-4 客户端界面设计 83.2.3 客户端的功能实现1.初始化 WinSock 环境 与服务器端基本相同,具体
代码如下: // socket 函数建立套接字 WSAStartupMAKEWORD2 0 ampm_WSAData //初始化套接字 m_sockLocal socketAF_I
NET SOCK_DGRAM 0 //创建本地服务套接字 WSAAsyncSelectm_sockLocal GetSafeHwnd WM_SOCKET FD_READ //选择需要处理的网络时间 m_addr_in.sin_addr.S_un.S_addr inet_addrm_Str_IP //服务器 IP 地址 m_addr_in.sin_family AF_INET //协议族 m_addr_in.sin_port htons9001 //服务器断口 bindm_sockLocal SOCKADDRampm_addr_in sizeofm_addr_in //绑定 在套接字建立好之后只需用以下两个函数就可以收发信息了,注意需指明长度。
//收发信息 recvfromm_sockLocal buf 1040 0 SOCKADDRampm_addrfrom ampm_fromlen sendtom_sockLocal buf 1024 0 SOCKADDRampm_addrto sizeofm_addrto2.与服务器连接断开的具体实现 当点击连接按钮后,客户端向服务器端发出一个连接请求信息,然后等待回应,如果连接不成功则返回,成功后则可进行消息的接收和发送。
若连接成功后用户点击断开连接按钮,则程序向服务器端发出断开连接信息。
具体实现
代码如下: 连接请求: //点击连接按钮,发送连接请求信息nt LanaenumLANA_ENUM lenumNCB ncbZeroMemoryampncbsizeofNCBncb.ncb_commandNCBENUMncb.ncb_bufferPUCHARlenumncb.ncb_lengthsizeofLANA_ENUMifNetbiosampncbNRC_GOODRETAfxMessageBoxquot枚举 LANA 失败quotreturn ncb.ncb_retcodereturn NRC_GOODRET 9int LanaresetLANA_ENUM lenumUCHAR ucmaxsessionUCHAR unmaxnameBOOL bfirstname NCB ncb ZeroMemoryampncbsizeofNCB ncb.ncb_commandNCBRESET ncb.ncb_callname0ucmaxsession ncb.ncb_callname1unmaxname ncb.ncb_callname2UCHARbfirstname forint i0iltlenum-gtlengthi ncb.ncb_lana_numlenum-gtlanai ifNetbiosampncbNRC_GOODRET AfxMessageBoxquot复位 LANA 失败quot return ncb.ncb_retcode return NRC_GOODRETint Addnameint lanachar nameUCHAR ampnumNCB ncbZeroMemoryampncbsizeofNCBncb.ncb_commandNCBADDNAMEmemsetncb.ncb_name NCBNAMSZstrncpychar ncb.ncb_namenamestrlennameifNetbiosampncbNRC_GOODRETAfxMessageBoxquot添加唯一名失败quotreturn ncb.ncb_retcode 10numncb.ncb_numreturn NRC_GOODRETint Datagramsendbcint lanaUCHAR numchar sendbcbufferint buflenNCB ncb ZeroMemoryampncbsizeofNCBncb.ncb_commandNCBDGSENDBCncb.ncb_lana_numlanancb.ncb_numnumncb.ncb_bufferPUCHARsendbcbufferncb.ncb_lengthbuflenifNetbiosampncbNRC_GOODRET AfxMessageBoxquot发送广播数据报失败quot return ncb.ncb_retcodereturn NRC_GOODRETint DatagramrecvbcPNCB pncbint lanaUCHAR numchar recvbcbufferint buflen pncb-gtncb_commandNCBDGRECVBCASYNCH pncb-gtncb_lana_numlana pncb-gtncb_numnum pncb-gtncb_bufferPUCHARrecvbcbuffer pncb-gtncb_lengthbuflen ifNetbiospncbNRC_GOODRET AfxMessageBoxquot接收广播数据报失败quot return pncb-gtncb_retcode return NRC_GOODRET //在接收时判断信息 11 int Datagramsendint lanaUCHAR numchar namechar sendbcbufferint buflen NCB ncb ZeroMemoryampncbsizeofNCB ncb.ncb_commandNCBDGSEND ncb.ncb_lana_numlana ncb.ncb_numnum ncb.ncb_bufferPUCHARsendbcbuffer ncb.ncb_lengthbuflen memsetncb.ncb_name NCBNAMSZ strncpychar ncb.ncb_namenamestrlenname ifNetbiosampncbNRC_GOODRET AfxMessageBoxquot发送定向数据报失败quot return ncb.ncb_retcode return NRC_GOODRETint DatagramrecvbcPNCB pncbint lanaUCHAR numchar recvbcbufferint buflenHANDLE hevent pncb-gtncb_commandNCBDGRECVASYNCH pncb-gtncb_lana_numlana pncb-gtncb_numnum pncb-gtncb_bufferPUCHARrecvbcbuffer pncb-gtncb_lengthbuflen pncb-gtncb_eventhevent ifNetbiospncbNRC_GOODRET AfxMessageBoxquot接收定向数据报失败quot return pncb-gtncb_retcode return NRC_GOODRET 12int Sendint lanaint lsnchar sendbcbufferint buflen NCB ncb ZeroMemoryampncbsizeofNCB ncb.ncb_commandNCBSEND ncb.ncb_lana_numlana ncb.ncb_bufferPUCHARsendbcbuffer ncb.ncb_lsnlsn ncb.ncb_lengthbuflen ifNetbiosampncbNRC_GOODRET AfxMessageBoxquot发送会话失败quot return ncb.ncb_retcode return NRC_GOODRETint Recvint lanaint lsnchar recvbcbufferint buflen NCB ncb ZeroMemoryampncbsizeofNCB ncb.ncb_commandNCBRECV ncb.ncb_lana_numlana ncb.ncb_bufferPUCHARrecvbcbuffer ncb.ncb_lsnlsn ncb.ncb_lengthbuflen ifNetbiosampncbNRC_GOODRET AfxMessageBoxquot接收会话失败quot return ncb.ncb_retcode return NRC_GOODRETvoid CALLBACK listencallbackPNCB pncb 13 AfxMessageBoxquot有一个用户连入quotint ListenPNCB pncbint lanachar servernameHANDLE heventpncb-gtncb_commandNCBLISTENASYNCHpncb-gtncb_lana_numlanamemsetpncb-gtncb_name NCBNAMSZstrncpychar pncb-gtncb_nameservernamestrlenservernamememsetpncb-gtncb_callname NCBNAMSZpncb-gtncb_callname0pncb-gtncb_eventhevent//pncb-gtncb_postlistencallbackifNetbiospncbNRC_GOODRET AfxMessageBoxquot监听失败quot return pncb-gtncb_retcodereturn NRC_GOODRETint ConnectPNCB pncbint lanachar servernamechar clientnameHANDLE heventpncb-gtncb_commandNCBCALLASYNCHpncb-gtncb_lana_numlanamemsetpncb-gtncb_name NCBNAMSZstrncpychar pncb-gtncb_nameclientnamestrlenclientnamememsetpncb-gtncb_callname NCBNAMSZstrncpychar pncb-gtncb_callnameservernamestrlenservernamepncb-gtncb_eventhevent 14 ifNetbiospncbNRC_GOODRET AfxMessageBoxquot连接失败quot return pncb-gtncb_retcode return NRC_GOODRET 发送断开请求: 该功能就只是给服务器发送一个特定的断开请求消息,服务器根据消息将该客户端的IP 从 ListBox 和链表中删除,以达到断开的目的。
sendtom_sockLocal bufDisConnect 11 0 SOCKADDRampm_addrto sizeofm_addrto 154 设计结果与分析4.1 设计结果 下面使用一些程序运行的截图的对程序最终结果进行简单的阐述: 下图是客户端连接服.