ImageVerifierCode 换一换
格式:DOCX , 页数:20 ,大小:399.42KB ,
资源ID:5729787      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5729787.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(基于Socket的即时通讯系统.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

基于Socket的即时通讯系统.docx

1、基于Socket的即时通讯系统评阅教师评语:课程设计成绩考勤成绩实做成绩报告成绩总评成绩指导教师签名:综合课程设计设 计 报 告论文题目: 基于Socket的即时通讯系统 学院(系): 电子信息与自动化学院 班 级: 721 学生姓名: 学号 指导教师: 时间: 2011 年 6月 7日 到 2011 年 6 月 17日一、 设计目的通过综合课程设计,使学生能够运用数字信号处理、信号与系统、通信原理、面向对象的程序设计、计算机通信网、通信协议开发及应用等课程的知识来设计一个基于Socket的即时通讯系统,培养学生的动手能力以及分析问题、解决问题的能力。二、 设计内容一个基于Socket的即时通

2、讯系统的多人聊天软件三、 设计要求(一)基本要求1 熟练掌握面向对象的程序设计方法;2 实现点对点通讯,能进行文字对话传输,包括客户端与服务器端;3 能对系统参数进行配置。(二)提高要求1、实现文件、图片传输;2、语音对话(两人及两人以上);3、友好的对话界面。四、 设计原理1 TCP/IP简介 TCP/IP的历史要追溯到70年代中期,当时ARPA为了实现异种网之间的互连(interconnection)与互通(intercommunication),大力资助网间网技术的研究和开发,于1977年到1979年推出目前形式的TCP/IP体系结构和协议规范.到今天,TCP/IP技术以及Interne

3、t网间网已经为广大计算机工作者,机算机厂商和机算机用户所接受.据统计,到1990年,Internet以包含遍布欧美的五千个活动网络,超过三十万台机算机.作为一种事实上的工标准,TCP/IP技术方兴未艾.2 TCP/IP的网络分层结构 对TCP/IP协议来说,TCP提供传输层服务,IP提供网络层服务.TCP/IP协议组(或Internet协议组)的分层结构及其与OSI模型的对应关系如图4所示.图中有关协议的名称及其基本含义如下: (1) TCP. 为传输控制协议(Transmission Control Protocol).它是提供给用户进程的一个可靠的全双工字节流的面向连接的协议.大多数Int

4、ernet应用程序使用TCP.因为TCP使用IP,所以整个Internet协议组也常称为TCP/IP协议组. (2) UDP. 为用户数据报协议 (User Datagram Protocol). (3) ICMP. 为网间报文控制协议 (Internet Control Message Protocol). (4) IP. 网间协议 (Internet Protocol). IP协议是为TCP,UDP和ICMP提供分组发送服务协议. (5) ARP. 地址转换协议. (6) RARP. 反向地址转换协议.3 Socket编程界面 (1) Socket 原理 Socket编程界面由4BSD U

5、NIX首先提出,目的是解决网间网进程通信问题.Socket接口为进程间通信提供了一种新的手段,它不但能用于同一机器中的进程之间的通信,而且支持网络通信功能.Socket具有类型,反应了对用户透明的通信特性. 一个完整的Socket连接用一个相关描述: 协议,本地地址,本地端口,远地地址,远地端口 Socket 是面向客户-服务器模型而设计的,针对客户和服务器程序提供不同的Socket系统调用. (2) Socket系统调用 不管Socket内部机制如何,它提供给应用程序员的最终界面是一组系统功能调用.下面,我们一一给出重要的Socket系统调用. 1. 创建 Socket - socket()

6、 调用格式如下: sockid = socket (af,type,protocol) af : 地址族,指本socket所用地址类型. type : 类型,指创建socket的应用程序所希望的通信服务器类型. protocol : 协议,指本socket请求的协议. 2. 指定本地地址 - bind()调用 bind()将本地socket地址与所创建的socket联系起来,即将本socket地址赋予socket,以指定本地半相关.bind()的作用相当于给socket命名,调用格式为: bind (sockid,localaddr,addrlen) sockid : socket号. loc

7、aladdr : 本地socket地址. addrlen : 地址长度. 3. 建立socket连接 - connect () 与 accept ()调用 这两个系统调用用于完成整个相关的建立.其中connect用于建立连接 .调用格为: connect (sockid,destaddr,addrlen) destaddr : 指向对方socket地址(信宿地址)结构的指针. accept : 用于面向连接的服务器,其调用格式为: newsock = accept (sockid,clientaddr,paddrlen) clientaddr : 指向客户socket地址指针. paddrle

8、n : 客户socket地址长度. 4. listen() 调用 此调用用于面向连接服务器,表明它愿意接收连接,listen()在accept()之前调用,格式为: listen (sockid,quelen) quelen : 请求队列长度. 5. 发送数据 - write(),writev(),send()与sendto(),sendmsg() 用于socket数据发送的系统调用一共有五个,其中三个,write(),writev()和send()用于面向连接传输,其余两个用于无连接传输.面向连接的调用可以不指定信宿地址,而无连接的调用必须指定.假如无连接socket的双方均调用过conne

9、ct(),可以认为是建立有连接的socket,也可以面向连接调用发送数据. 三个面向连接调用三者的格式大致相同: write (sockid,buff,bufflen) : 缓冲发送 writev (sockid,iovector,vectorlen) : 集中发送 send (sockid,buff,bufflen,flags) : 可控缓冲发送 其中buff指向发送缓冲区的指针,bufflen是发送缓冲区大小. 用于无连接数据发送的调用有两个: sendto (sockid,buff,bufflen,flags,dsadd,addrlen) sendmsg (sockid,message,

10、flags):可控集中无连接发送. 6. 接收数据 - read(),readv(),recv()与recvfrom(),recvmsg() 接收数据与发送数据系统调用是一一对应的,两者参数的最大区别是,前者buffer是一个指针,其所指单元初值为欲读数据长度,调用后的值是实际读出的值.4 客户-服务器模型的Socket实现框架 1)客户-服务器模型时序图 下图是面向连接客户-服务器模型的典型时序图 服务器 客户 socket() socket() bind() bind() listen() accept() 等待客户连接请求 阻塞 connect() read() write() 2)服务

11、器socket地址的确定在客户-服务器模型中,所有的作用者都是客户首先发起的(如连接请求,服务请求等),因此客户必须要知道服务器socket地址,另外,客户调用服务器之前,可以在命令行中给出服务器所在主机的域名,根据域名可以获得服务器主机的地址,系统调用为:hp=gethostbyname(host).其中host可以是服务器主机域名,返回hp是一个指向主机地址结构的指针。五、 软件设计(附程序流程图、源程序清单)1. 程序流程图2.源程序清单void CChatRoomDlg:DlgAllInit() CheckRadioButton(IDC_RADIO_CLIENT, IDC_RADIO_

12、SERVER, IDC_RADIO_CLIENT); SetDlgItemText(IDC_IP_ADDR, _T(127.0.0.1); / 初始化ip地址为本机地址。 SetDlgItemText(IDC_CONNECT_PORT, _T(5566); / 初始化端口。 SetDlgItemText(IDC_LISTEN_PORT, _T(5566);EnableWindow(IDC_STOP_CLIENT, FALSE); EnableWindow(IDC_LISTEN_PORT, FALSE); EnableWindow(IDC_STOP_SERVER, FALSE); EnableW

13、indow(IDC_START_SERVER, FALSE); EnableWindow(IDC_STATIC_LISTEN_PORT, FALSE); / 初始化按键启用or禁用。 EnableWindow(IDC_SENDMSG, FALSE);BOOL CChatRoomDlg:EnableWindow(UINT uID, BOOL bEnable) return GetDlgItem(uID)-EnableWindow(bEnable);void CChatRoomDlg:ExtendDiaog(BOOL bShow) static CRect m_DlgRectLarge(0, 0,

14、 0, 0); static CRect m_DlgRectSmall(0, 0, 0, 0); static CRect m_GroupRectLarge(0, 0, 0, 0); static CRect m_GroupRectSmall(0, 0, 0, 0); / 设置 窗口大小 if ( m_DlgRectLarge.IsRectNull() ) GetWindowRect(&m_DlgRectLarge); m_DlgRectSmall = m_DlgRectLarge; m_DlgRectSmall.right -= 220; :GetWindowRect(GetDlgItem(

15、IDC_FRAME)-GetSafeHwnd(), &m_GroupRectLarge); m_GroupRectSmall = m_GroupRectLarge; m_GroupRectSmall.right -= 220; / 设置 窗口 伸缩大小范围 if ( bShow ) bShowAll = TRUE; SetWindowPos(NULL, 0, 0, m_DlgRectLarge.Width(), m_DlgRectLarge.Height(), SWP_NOZORDER | SWP_NOMOVE); :SetWindowPos(GetDlgItem(IDC_FRAME)-Get

16、SafeHwnd(), NULL, 0, 0, m_GroupRectLarge.Width(), m_GroupRectLarge.Height(), SWP_NOZORDER | SWP_NOMOVE); else bShowAll = FALSE; SetWindowPos(NULL, 0, 0, m_DlgRectSmall.Width(), m_DlgRectSmall.Height(), SWP_NOZORDER | SWP_NOMOVE); :SetWindowPos(GetDlgItem(IDC_FRAME)-GetSafeHwnd(), NULL, 0, 0, m_Group

17、RectSmall.Width(), m_GroupRectSmall.Height(), SWP_NOZORDER | SWP_NOMOVE); void CChatRoomDlg:OnBnClickedNetset() if ( bShowAll ) ExtendDiaog(FALSE); else ExtendDiaog(TRUE); / 设置按键“网络设置”的作用 void CChatRoomDlg:OnBnClickedStartServer() m_hListenThread = CreateThread(NULL, 0, ListenThreadFunc, this, 0, NU

18、LL);void CChatRoomDlg:ShowMsg(CString strMsg) m_MsgEdit.SetSel(-1, -1); m_MsgEdit.ReplaceSel(strMsg+_T(rn);void CChatRoomDlg:RemoveClientFromArray(CClientItem in_Item) for( int idx = 0; idx ) + strMsg; ShowMsg(strMsg); SendClientsMsg(strMsg); else if (m_bIsServer = FALSE) CString strTmp = _T(张智超的客户端

19、:) + strMsg; ShowMsg(strTmp); int iSend = send(m_ConnectSock, (char *)strMsg.GetBuffer(), strMsg.GetLength()*sizeof(TCHAR), 0); strMsg.ReleaseBuffer(); else AfxMessageBox(_T(请您先进入聊天室!); SetDlgItemText(IDC_INPUT_MSG, _T(); / socket 基本应用void CChatRoomDlg:OnBnClickedStartClient() m_hConnectThred = Crea

20、teThread(NULL, 0, ConnectThreadFunc, this, 0, NULL);void CChatRoomDlg:SendClientsMsg(CString strMsg, CClientItem *pNotSend) TCHAR szBufMAX_BUF_SIZE = 0; _tcscpy_s(szBuf, MAX_BUF_SIZE, strMsg); for( INT_PTR idx = 0; idx m_Socket != m_ClientArray.GetAt(idx).m_Socket | pNotSend-hThread != m_ClientArray

21、.GetAt(idx).hThread | pNotSend-m_strIp != m_ClientArray.GetAt(idx).m_strIp) send(m_ClientArray.GetAt(idx).m_Socket, (char *)szBuf, _tcslen(szBuf)*sizeof(TCHAR), 0); void CChatRoomDlg:OnEnChangeInputMsg() CString strMsg; GetDlgItemText(IDC_INPUT_MSG, strMsg); if ( strMsg.IsEmpty() ) EnableWindow(IDC_

22、SENDMSG, FALSE); else EnableWindow(IDC_SENDMSG); void CChatRoomDlg:StopClient() bShutDown = TRUE; DWORD dwRet = WaitForSingleObject(m_hConnectThred, 1000); if ( dwRet != WAIT_OBJECT_0 ) TerminateThread(m_hConnectThred, -1); closesocket(m_ConnectSock); m_hConnectThred = NULL; m_ConnectSock = INVALID_

23、SOCKET; m_bIsServer = -1; bShutDown = FALSE;void CChatRoomDlg:StopServer() UINT nCount = m_ClientArray.GetCount(); HANDLE *m_pHandles = new HANDLEnCount+1; m_pHandles0 = m_hListenThread; for( int idx = 0; idx nCount; idx+ ) m_pHandlesidx+1 = m_ClientArray.GetAt(idx).hThread; bShutDown = TRUE; DWORD

24、dwRet = WaitForMultipleObjects(nCount+1, m_pHandles, TRUE, 1000); if ( dwRet != WAIT_OBJECT_0 ) for( INT_PTR i = 0; i m_ClientArray.GetCount(); i+ ) TerminateThread(m_ClientArray.GetAt(i).hThread, -1); closesocket(m_ClientArray.GetAt(i).m_Socket); TerminateThread(m_hListenThread, -1); closesocket(m_

25、ListenSock); delete m_pHandles; m_hListenThread = NULL; m_ListenSock = INVALID_SOCKET; m_bIsServer = -1; bShutDown = FALSE;void CChatRoomDlg:OnBnClickedStopClient() StopClient(); ShowMsg(_T(停止客户端成功!); EnableWindow(IDC_START_CLIENT); EnableWindow(IDC_STOP_CLIENT, FALSE);void CChatRoomDlg:OnBnClickedS

26、topServer() StopServer(); ShowMsg(_T(停止服务器成功!); EnableWindow(IDC_START_SERVER); EnableWindow(IDC_STOP_SERVER, FALSE);void CChatRoomDlg:OnBnClickedRadioClient() int iRet = -1; if ( m_bIsServer = TRUE ) int iRet = MessageBox(_T(您是聊天室的服务器端,如果您退出,所有的客户端都将掉线!rn您确定退出吗?), _T(提示), MB_OKCANCEL | MB_ICONWARNI

27、NG); if ( iRet = IDOK ) StopServer(); else CheckRadioButton(IDC_RADIO_CLIENT, IDC_RADIO_SERVER, IDC_RADIO_SERVER); if ( iRet = IDOK | m_bIsServer = -1 ) EnableWindow(IDC_IP_ADDR); EnableWindow(IDC_CONNECT_PORT); EnableWindow(IDC_STATIC_SERVER_IP); EnableWindow(IDC_STATIC_SERVER_PORT); EnableWindow(IDC_START_CLIENT); EnableWindow(IDC_STOP_CLIENT, FALSE); EnableWindow(IDC_LISTEN_PORT, FALSE); EnableWindow(IDC_STOP_SERVER, FALSE); EnableWindow(IDC_START_SERVER, FALSE); EnableWindow(IDC_STATIC_L

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

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