欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > DOC文档下载  

    计算机网络课程设计 用WINSOCK实现聊天室的VC++程序设计.doc

    • 资源ID:2386155       资源大小:39.50KB        全文页数:15页
    • 资源格式: DOC        下载积分:8金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要8金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    计算机网络课程设计 用WINSOCK实现聊天室的VC++程序设计.doc

    课程设计 计算机网络学生姓名: 学 号:10225509312 专业班级:计算机2093班指导老师: 用WINSOCK实现聊天室的VC+程序设计摘 要:WINSOCK 是在Windows进行网络通信编程的API接口,也是Windws网络编程的事实标准。在网络编程中最常用的方案便是客户机/服务器模型。本文提出了在客户机/服务器模型下用WINSOCK实现Internet中常见的聊天室软件的方案。关键词:套接字,WINSOCK,客户机/服务器,网络编程一:SOCKET简介80年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大学Berkeley分校提供了资金,让他们在UNIX操作系统下实现TCP/IP协议。在这个项目中,研究人员为TCP/IP网络通信开发了一个API(应用程序接口)。这个API称为Socket接口(套接字)。今天,SOCKET接口是TCP/IP网络最为通用的API,也是在INTERNET上进行应用开发最为通用的API。90年代初,由Microsoft联合了其他几家公司共同制定了一套WINDOWS下的网络编程接口,即WindowsSockets规范。它是BerkeleySockets的重要扩充,主要是增加了一些异步函数,并增加了符合Windows消息驱动特性的网络事件异步选择机制。WINDOWSSOCKETS规范是一套开放的、支持多种协议的Windows下的网络编程接口。从1991年的1.0版到1995年的2.0.8版,经过不断完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成为Windows网络编程的事实上的标准。目前,在实际应用中的WINDOWSSOKCETS规范主要有1.1版和2.0版。两者的最重要区别是1.1版只支持TCP/IP协议,而2.0版可以支持多协议。2.0版有良好的向后兼容性,任何使用1.1版的源代码,二进制文件,应用程序都可以不加修改地在2.0规范下使用。SOCKET实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有SOCKET接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个SOCKET接口来实现。在应用开发中就像使用文件句柄一样,可以对SOCKET句柄进行读,写操作。二:基于WINDOWS SOCKET的应用开发介绍。在WINDOWS95/98,WINDOWSNT进行WINSOCK开发使用的编程语言有很多,VC+,JAVA,DELPHI,VB等。其中VC时使用最普遍,和WINSOCK结合最紧密的。并且VC+对原来的WindowsSockets库函数进行了一系列封装,继而产生了CAsynSocket、CSocket、CSocketFile等类,它们封装着有关Socket的各种功能,是编程变得更加简单。但如果你是一个WINSOCK编程的初学者,那么建议你在一开始还是学习WINSOCK最基本的API函数进行编程,这样可以大大加深对WINSOCK的了解,对将来很有好处。在VC中进行WINSOCK的API编程开发,需要使用到下面三个文件:1 WINSOCK.H: 这是WINSOCK API的头文件。2 WSOCK32.LIB: WINSOCK API连接库文件。在使用中,一点要把它作为项目的非缺省的连接库包含到项目文件中去。3 WINSOCK.DLL: WINSOCK的动态连接库,位于WINDOWS的安装目录下。可以看到,WINSOCK。DLL位于TCP/IP协议栈和应用程序之间。也就是说,WINSOCK管理与TCP/IP协议的接口。在一开始WINSOCK的应有开发时,你不必对TCP/IP协议有很深刻的了解。但是,如果想成为一个为网络编程的高手,就一定要对下层了解得十分清楚。在网络编程中最常用的方案便是客户机/服务器模型。在这种方案中客户应用程序向服务器程序请求服务。一个服务程序通常在一个众所周知的地址监听对服务的请求,也就是说,服务进程一直处于休眠状态,直到一个客户对这个服务的地址提出了连接请求。在这个时刻,服务程序被“惊醒”并且为客户提供服务对客户的请求作出适当的反应。虽然基于连接协议(流套接字)的服务是设计客户机/服务器应用程序时的标准,但有些服务也是可以通过无连接协议(数据报套接字)提供的。一般在使用中,面向连接协议的SOCKET编程模型应用最为广泛,因为面向连接协议提供了一系列的数据纠错功能,可以保证在网络上传输的数据及时、无误地到达对方。 总的来说,使用SOCKET接口(面向连接或无连接)进行网络通信时,必须按下面简单的四步进行处理:1、程序必须建立一个 SOCKET。2、程序必须按要求配置此SOCKET。也就是说,程序要么将此SOCKET连接到远方的主机上,要么给此SOCKET指定一个本地协议端口。3、程序必须按要求通过此SOCKET发送和接收数据。4、程序必须关闭此SOCKET。三:WINSOCK API主要函数简介作者利用WINSOCK API 编写了一个具有聊天室功能的应用程序,可用作学习 WINSOCK 程序设计的参照。WINSOCK API 包括很多函数,但其中最常用,包括在文章所附源程序中的有:注:只是有关函数的简要说明,具体规则、说明请参见VC+帮助和WINSOCK规范。1、WSAStartup():连结应用程序与 Windows Sockets DLL 的第一个函数。说明: 此函数是应用程序调用 Windows Sockets DLL函数中的第一个,也唯有此函数呼叫成功後,才可以再调用其他 Windows Sockets DLL 的函数。2、WSACleanup():结束 Windows Sockets DLL 的使用。说明: 当应用程序不再需要使用 Windows Sockets DLL时,须调用此函数来注销使用,以便释放其占用的资源。3、 socket():建立Socket。说明: 此函数用来建立一 Socket 描述字,并为此 Socket 建立其所使用的资源。4、 closesocket():关闭某一Socket。说明: 此一函数是用来关闭某一 Socket。5、 bind():将一本地地址与一个SOCKET描述字连接在一起。说明:此函数在服务程序上使用,是调用监听函数listen()必须要调用的函数。6、 listen():设定 Socket 为监听状态,准备被连接。说明: 此函数在服务程序上使用,来设定 Socket 进入监听状态,并设定最多可有多少个在未真正完成连接前的客户端的连接要求。(目前最大值限制为 5, 最小值为1)7、 accept():接受某一Socket的连接要求,以完成面向连接的客户端 Socket 的连接请求。说明: 服务端应用程序调用此函数来接受客户端Socket 连接请求,accept() 函数的返回值为一新的 Socket,新 Socket 就可用来在服务端和客户端之间的信息传递接收,而原来 Socket 仍然可以接收其他客户端的连接要求。8、 connect():要求连接某一Socket到指定的网络上服务端。说明: 此函数用在客户端,用来向服务端要求建立连接。当连接建立完成後,客户端即可利用此 Socket 来与服务端进行信息传递。9、 recv():从面向连接的 Socket 接收信息。说明: 此函数用来从面向连接的 Socket 接收信息。10、send():使用面向连接的 Socket 发送信息。说明: 此函数用来从面向连接的 Socket 发送信息。11、WSAAsyncSelect():要求某一 Socket 有事件 (event) 发生时通知使用者。说明: 此函数用来请求Windows Sockets DLL 为窗口句柄发一条消息无论它何时检测到由lEvent参数指明的网络事件。要发送的消息由wMsg参数标明.被通知的套接口由s标识。本函数自动将套接口设置为非阻塞模式。lEvent参数由下表中列出的值组成。值 意义FD_READ 欲接收读准备好的通知。FD_WRITE 欲接收写准备好的通知。FD_OOB 欲接收带边数据到达的通知。FD_ACCEPT 欲接收将要连接的通知。FD_CONNECT 欲接收已连接好的通知。FD_CLOSE 欲接收套接口关闭的通知。这个函数可以认为是 WINSOCK API 中最为重要的一个函数。要想使用好这个函数,你必须对 WINDOWS 编程的事件驱动和消息传递有很清楚的了解。四:聊天室应用程序的设计说明:软件功能:Internet上可以提供一种叫IRC 的服务。使用者通过客户端的程序登录到IRC服务器上,就可以与登录在同一IRC服务器上的客户进行交谈,这也就是平常所说的聊天室。在这里,给出了一个在运行TCP/IP协议的网络上实现IRC服务的程序。软件使用说明:首先,在一台计算机上运行服务端程序,然后就可以在同一网络的其他计算机上运行客户端程序,登录到服务器上,各个客户之间就可以聊天了。软件设计要点:1、服务端核心代码在 CServerViwe 类中,有一个 SOCKET 变量 m_hServerSocket 和 SOCKET 数组 m_aClientSocketMAXClient(MAXClient:所定义的接收连接客户的最大数目),m_hServerSocket 用来在指定的端口(>1000)进行侦听,如果有客户端请求连接,则在 m_aClientSocket 数组中查找一个空 socket,将客户端的地址赋予此 socket。每当一个 ClientSocket 接收到信息,都将会向窗口发一条消息。程序接收到这个消息后,再把接收到的信息发送给每一个 ClientSocket。2、客户端客户端比较简单,核心代码在 CClientDlg 类中。只有一个 socket 变量 m_hSocket,与服务端进行连接。连接建立好后,通过此 SOCKET 发送和接收信息。为了简化设计,用户名在客户端控制,服务器端只进行简单的接收信息和“广播”此信息,不进行名字校验,也就是说,可以有同名客户登录到服务端。这个程序设计虽然简单,但是已经具备了聊天室的最基本的功能。程序在VC+ 6.0 下编译通过,在使用 TCP/IP 协议的 WINDOWS 95/98 对等局域网 和使用 TCP/IP 协议的 WINDOWS NT 局域网上运行良好。 程序代码:import java.applet.*; import java.awt.*; import java.io.*; import .*; import java.awt.event.*; public class ChatClient extends Applet protected boolean loggedIn;/登入状态 protected Frame cp;/聊天室框架 protected static int PORTNUM=7777; /缺省端口号7777 protected int port;/实际端口号 protected Socket sock; protected BufferedReader is;/用于从sock读取数据的BufferedReader protected PrintWriter pw;/用于向sock写入数据的PrintWriter protected TextField tf;/用于输入的TextField protected TextArea ta;/用于显示对话的TextArea protected Button lib;/登入按钮 protected Button lob;/登出的按钮 final static String TITLE ="Chatroom applet>>>>>>>>>>>>>>>>>>>>>>>>" protected String paintMessage;/发表的消息 public ChatParameter Chat; public void init() paintMessage="正在生成聊天窗口" repaint(); cp=new Frame(TITLE); cp.setLayout(new BorderLayout(); String portNum=getParameter("port");/呢个参数勿太明 port=PORTNUM; if (portNum!=null) /书上是portNum=null,十分有问题 port=Integer.parseInt(portNum); /CGI ta=new TextArea(14,80); ta.setEditable(false);/read only attribute ta.setFont(new Font("Monospaced",Font.PLAIN,11); cp.add(BorderLayout.NORTH,ta); Panel p=new Panel(); Button b; /for login button p.add(lib=new Button("Login"); lib.setEnabled(true); lib.requestFocus(); lib.addActionListener(new ActionListener() public void actionPerformed(ActionEvent e) login(); lib.setEnabled(false); lob.setEnabled(true); tf.requestFocus();/将键盘输入锁定再右边的文本框中 ); /for logout button p.add(lob=new Button ("Logout"); lob.setEnabled(false); lob.addActionListener(new ActionListener() public void actionPerformed(ActionEvent e) logout(); lib.setEnabled(true); lob.setEnabled(false); lib.requestFocus(); ); p.add(new Label ("输入消息:"); tf=new TextField(40); tf.addActionListener(new ActionListener() public void actionPerformed(ActionEvent e) if(loggedIn) /pw.println(Chat.CMD_BCAST+tf.getText();/Chat.CMD.是咩野来? int j=tf.getText().indexOf(":"); if(j>0) pw.println(Chat.CMD_MESG+tf.getText(); else pw.println(Chat.CMD_BCAST+tf.getText(); tf.setText("");/勿使用flush()? ); p.add(tf); cp.add(BorderLayout.SOUTH,p); cp.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent e) /如果执行了setVisible或者dispose,关闭窗口 ChatClient.this.cp.setVisible(false); ChatClient.this.cp.dispose(); logout(); ); cp.pack();/勿明白有咩用? /将Frame cp放在中间 Dimension us=cp.getSize(), them=Toolkit.getDefaultToolkit().getScreenSize(); int newX=(them.width-us.width)/2; int newY=(them.height-us.height)/2; cp.setLocation(newX,newY); cp.setVisible(true); paintMessage="Window should now be visible" repaint(); /登录聊天室 public void login() if(loggedIn) return; try sock=new Socket(getCodeBase().getHost(),port); is=new BufferedReader(new InputStreamReader(sock.getInputStream(); pw=new PrintWriter(sock.getOutputStream(),true); catch(IOException e) showStatus("Can't get socket: "+e); cp.add(new Label("Can't get socket: "+e); return; /构造并且启动读入器,从服务器读取数据,输出到文本框中 /这里,长成一个线程来避免锁住资源(lockups) new Thread (new Runnable() public void run() String line; try while(loggedIn &&(line=is.readLine()!=null) ta.appendText(line+"n"); catch(IOException e) showStatus("我的天啊,掉线了也!"); return; ).start(); /假定登录(其实只是打印相关信息,并没有真正登录) / pw.println(Chat.CMD_LOGIN+"AppletUser"); pw.println(Chat.CMD_LOGIN+"AppletUser"); loggedIn =true; /模仿退出的代码 public void logout() if(!loggedIn) return; loggedIn=false; try if(sock!=null) sock.close(); catch(IOException ign) / 异常处理哦 /没有设置stop的方法,即使从浏览器跳到另外一个网页的时候 /聊天程序还可以继续运行 public void paint(Graphics g) Dimension d=getSize(); int h=d.height; int w=d.width; g.fillRect(0,0,w,2); g.setColor(Color.black); g.drawString(paintMessage,10,(h/2)-5); 聊天室服务器端 import .*; import java.io.*; import java.util.*; public class ChatServer /聊天室管理员ID protected final static String CHATMASTER_ID="ChatMaster" /系统信息的分隔符 protected final static String SEP=": " /服务器的Socket protected ServerSocket servSock; /当前客户端列表 protected ArrayList clients; /调试标记 protected boolean DEBUG=false; public ChatParameter Chat; /主方法构造一个ChatServer,没有返回值 public static void main(String argv) System.out.println("Chat server0.1 starting>>>>>>>>>>>>>>>>"); ChatServer w=new ChatServer(); w.runServer(); System.out.println("*ERROR* Chat server0.1 quitting"); /构造和运行一个聊天服务 ChatServer() Chat=new ChatParameter(); clients=new ArrayList(); try servSock=new ServerSocket(7777);/实有问题拉,不过可能是他自己定义既一个class. System.out.println("Chat Server0.1 listening on port:"+7777); catch(Exception e) log("IO Exception in ChatServer.<init>"); System.exit(0); public void runServer() try while(true) Socket us=servSock.accept(); String hostName=us.getInetAddress().getHostName(); System.out.println("Accpeted from "+hostName); /一个处理的线程 ChatHandler cl=new ChatHandler(us,hostName); synchronized(clients) clients.add(cl); cl.start(); if(clients.size()=1) cl.send(CHATMASTER_ID,"Welcome!You are the first one here"); else cl.send(CHATMASTER_ID,"Welcome!You are the latest of"+ clients.size()+" users."); catch(Exception e) log("IO Exception in runServer:"+e); System.exit(0); protected void log(String s) System.out.println(s); /处理会话的内部的类 protected class ChatHandler extends Thread /客户端scoket protected Socket clientSock; /读取socket的BufferedReader protected BufferedReader is ; /在socket 上发送信息行的PrintWriter protected PrintWriter pw; /客户端出主机 protected String clientIP; /句柄 protected String login; public ChatHandler (Socket sock,String clnt)throws IOException clientSock=sock; clientIP=clnt; is=new BufferedReader( new InputStreamReader(sock.getInputStream(); pw=new PrintWriter (sock.getOutputStream(),true); /每一个ChatHandler是一个线程,下面的是他的run()方法 /用于处理会话 public void run() String line; try while(line=is.readLine()!=null) char c=line.charAt(0);/我顶你老母啊 ,果只Chat.CMD咩xx冇定义 扑啊/! line=line.substring(1); switch(c) /case Chat.CMD_LOGIN: case 'l': if(!Chat.isValidLoginName(line) send(CHATMASTER_ID,"LOGIN"+line+"invalid"); log("LOGIN INVALID from:"+clientIP); continue; login=line; broadcast(CHATMASTER_ID,login+" joins us,for a total of"+ clients.size()+" users"); break; / case Chat.CMD_MESG: case 'm': if(login=null) send(CHATMASTER_ID,"please login first"); continue; int where =line.indexOf(Chat.SEPARATOR); String recip=line.substring(0,where); String mesg=line.substring (where+1); log("MESG: "+login+"->"+recip+": "+mesg); ChatHandler cl=lookup(recip); if(cl=null) psend(CHATMASTER_ID,recip+"not logged in."); else cl.psend(login,mesg); break; /case Chat.CMD_QUIT: case 'q': broadcast(CHATMASTER_ID,"Goodbye to "+login+""+clientIP); close(); return;/ChatHandler结束 / case Chat.CMD_BCAST: case 'b': if(login!=null) broadcast(login,line); else log("B<L FROM"+clientIP); break; default: log("Unknow cmd"+c+"from"+login+""+clientIP); catch(IOException e) log("IO Exception :"+e); finally /sock 结束,我们完成了 /还不能发送再见的消息 /得有简单的基于命令的协议才行 System.out.println(login+SEP+"All Done"); synchronized(clients) clients.remove(this); if(clients.size()=0) System.out.println(CHATMASTER_ID+SEP+ "I'm so lonely I could cry>>>>>"); else if(clients.size()=1) ChatHandler last=(ChatHandler)clients.get(0); last.send(CHATMASTER_ID,"Hey,you are talking to yourself again"); else broadcast(CHATMASTER_ID,"There are now"+clients.size()+" users"); protected void close() if(clientSock=null) log("close when not open"); return; try clientSock.close(); clientSock=null; catch(IOException e) log("Failure during close to "+clientIP); /发送一条消息给用户 public void send(String sender,String mesg) pw.println(sender+SEP+"*>"+mesg); /发送私有的消息 protected void psend(String sender ,String msg) send("<*"+sender+"*>",msg); /发送一条消息给所有的用户 public void broadcast (String sender,String mesg) System.out.println("Broadcasting"+sender+SEP+mesg); for(int i=0;i<clients.size();i+) ChatHandler sib=(ChatHandler)clients.get(i); if(DEBUG) System.out.println("Sending to"+sib); sib.send(sender,mesg); if(DEBUG) System.out.println("Done broadcast"); protected ChatHandler lookup(String nick) synchronized(clients) for(int i=0;i<clients.size();i+) ChatHandler cl=(ChatHandler)clients.get(i); if(cl.login.equals(nick) return cl; return null; /将ChatHandler对象转换成一个字符串 public String toString() return "ChatHandler"+login+"" public class ChatParameter public static final char CMD_BCAST='b' public static final char CMD_LOGIN='l' public static final char CMD_MESG='m' public static final char CMD_QUIT='q' public static final char SEPARATOR=':'/? public static final int PORTNUM=7777; public boolean isValidLoginName(String line) if (line.equals("CHATMASTER_ID") return false; return true; public void main(String argv)

    注意事项

    本文(计算机网络课程设计 用WINSOCK实现聊天室的VC++程序设计.doc)为本站会员(laozhun)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开