实现一个一对多的聊天程序.docx
- 文档编号:12759622
- 上传时间:2023-04-21
- 格式:DOCX
- 页数:16
- 大小:361.51KB
实现一个一对多的聊天程序.docx
《实现一个一对多的聊天程序.docx》由会员分享,可在线阅读,更多相关《实现一个一对多的聊天程序.docx(16页珍藏版)》请在冰豆网上搜索。
实现一个一对多的聊天程序
、
实现一个一对多的聊天程序
一、实验题目
实现一个一对多的聊天程序。
其基本过程如下:
服务器首先启动,创建套接字后等待客户的连接;客户启动以后,创建套接字,然后和服务器建立连接;连接建立后,客户机和服务器可以通过建立的套接字连接进行通信。
服务器和客户端可以是一台电脑上的两个进程,也可以分别部署在两台电脑上。
二、原理概述
TCP是一种可靠的、基于连接的网络传输协议,当两个网络进程准备进行通信时,都必须首先建立各自的一个套接口,其中服务器建立套接口后,侦听来自网络的客户连接请求,客户通过套接口,指定服务器的IP地址和端口号,便可和服务器通信。
聊天程序采用的是C/S通信模式,即客户/服务模式,它把一个使用划分成功能不同的两个部分,分别在不同的计算机上运行,其中一个为服务端程序,用来响应和提供固定的服务,一个为客户端程序,用来向服务端提出请求和要求某种服务。
在数量关系上,通常有一对多的(即一个服务端程序和一个客户端程序之间通信)。
客户机/服务器模式在操作过程中采取的是主动请示方式:
首先服务器方要先启动,并根据请示提供相应服务:
(1)打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求。
(2)等待客户请求到达该端口。
(3)接收到重复服务请求,处理该请求并发送应答信号。
(4)返回第二步,等待另一客户请求
(5)关闭服务器。
客户方:
(1)打开一通信通道,并连接到服务器所在主机的特定端口。
(2)向服务器发送服务请求报文,等待并接收应答;继续提出请求……
(3)请求结束后关闭通信通道并终止。
图1基于连接的服务者、客户服务流程图
三、设计方案
服务程序运行在服务器主机的某个端口上,一旦启动服务,它将在这个端口上倾听,等待客户程序发来的请求。
服务器的套接口用服务器套接口类(ServerSocket)来建立。
1、根据程序设计题目时首先明确程序的目的以及任务
2、利用JAVA语言编写程序,使用套接字来完成测试功能。
3、程序在Eclipcse环境中编译,根据错误提示查找分析并修改原程序
四、程序编写:
importjava.io.BufferedReader;
importjava.io.BufferedWriter;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.OutputStreamWriter;
import.ServerSocket;
import.Socket;
importjava.text.SimpleDateFormat;
importjava.util.ArrayList;
importjava.util.List;
/**
*@Title服务器
*@authorAllen
*@version2010-5-3下午08:
28:
36
*/
publicclassServer{
ServerSocketserver=null;
List
SimpleDateFormatsdf=newSimpleDateFormat("MM-ddHH:
mm:
ss");
publicvoidbegin(){
//读取客户端的userName
BufferedReaderbufUserName=null;
booleanstarted=false;
StringuserName=null;
try{
server=newServerSocket(8888);
System.out.println("服务器启动成功!
端口"+server.getLocalPort()+"监听中...");
started=true;
while(started){
Socketsocket=server.accept();
bufUserName=newBufferedReader(newInputStreamReader(socket.getInputStream()));
userName=bufUserName.readLine();
System.out.println("用户:
"+userName+" IP:
"+socket.getLocalSocketAddress()+" clientconnect...");
//bufUserName.close();
SCsc=newSC(socket);
newThread(sc).start();
clients.add(sc);
}
}catch(IOExceptione){
System.out.println("端口启动失败..."+e.getMessage()+"\n程序安全退出...");
System.exit(0);
}
}
publicstaticvoidmain(String[]args){
newServer().begin();
}
privateclassSCimplementsRunnable{
BufferedReaderbr=null;
BufferedWriterbw=null;
Socketsocket=null;
booleanisConnect=false;
publicSC(Socketsocket){
this.socket=socket;
try{
br=newBufferedReader(newInputStreamReader(socket.getInputStream()));
bw=newBufferedWriter(newOutputStreamWriter(socket.getOutputStream()));
isConnect=true;
}catch(IOExceptione){
e.printStackTrace();
}
}
publicvoidsendMessage(Stringstr){
try{
//bw.write(str+sdf.format(newDate())+"\n");
bw.write(str);
bw.newLine();
bw.flush();
}catch(IOExceptione){
e.printStackTrace();
}
}
publicvoidrun(){
try{
StringstrRead=null;
while(isConnect){
while((strRead=br.readLine())!
=null){
System.out.println("ServerreadLine..."+strRead);
for(inti=0;i clients.get(i).sendMessage(strRead); } } } }catch(Exceptione){ try{ br.close(); socket.close(); }catch(IOExceptione1){ e1.printStackTrace(); } e.getStackTrace(); }finally{ try{ if(br! =null)br.close(); if(bw! =null)bw.close(); if(socket! =null) { socket.close(); //s=null; } }catch(IOExceptione1){ e1.printStackTrace(); } } } } } importjava.awt.*; importjava.awt.event.*; importjava.io.*; import.Socket; import.UnknownHostException; importjava.text.SimpleDateFormat; importjava.util.Date; importjavax.swing.*; /** *@Title 客户端 *@authorAllen *@version2010-5-3下午08: 28: 47 */ publicclassClientextendsJFrame{ Socketsocket=null; JTextFieldjname=null; JTextFieldtext=newJTextField(); JTextAreaarea=newJTextArea(10,40); BufferedReaderbr=null; BufferedWriterbw=null; BufferedWritername_buf=null; booleanconnected=false; SimpleDateFormatsdf=newSimpleDateFormat("MM-ddHH: mm: ss"); staticStringuserName=null; publicClient(){ initFrame(); } publicstaticvoidmain(String[]args){ newClient(); } publicStringgetUserName(){ returnuserName; } publicvoidinitFrame(){ //setTitle(userName); setSize(400,300); setLocation(500,200); this.setResizable(false); JPanelpanel=newJPanel(); GridBagConstraintsgbc=newGridBagConstraints(); //GridBagLayoutlayout=newGridBagLayout(); FlowLayoutlayout=(FlowLayout)panel.getLayout(); layout.setAlignment(FlowLayout.RIGHT); gbc.anchor=GridBagConstraints.LINE_END; JButtonbtn_send=newJButton("send"); JButtonbtn_clear=newJButton("clear"); panel.setLayout(layout); panel.add(btn_clear); panel.add(btn_send,gbc); area.setLineWrap(true); area.setEditable(false); JScrollPanejsp=newJScrollPane(area); this.add(jsp,BorderLayout.NORTH); this.add(panel,BorderLayout.CENTER); this.add(text,BorderLayout.SOUTH); pack(); SendListenersendListener=newSendListener(); btn_send.addActionListener(sendListener); text.addActionListener(sendListener); btn_clear.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ text.setText(""); area.setText(""); text.requestFocus(); } }); //窗体监听 this.addWindowListener(newWindowAdapter(){ publicvoidwindowClosing(WindowEvente){ disConnect(); System.exit(0); System.out.println("窗体关闭了"); } } setVisible(true); connect(); ClientThreadclient=newClientThread(); newThread(client).start(); setTitle(userName); } //监听发送信息方法 privateclassSendListenerimplementsActionListener{ publicvoidactionPerformed(ActionEvente){ Stringstr=text.getText(); //area.setText(area.getText()+str+" "+sdf.format(newDate())+"\n"); text.setText(""); text.requestFocus(); try{ bw.write(userName+"说: "+str); bw.newLine(); bw.flush(); }catch(IOExceptione1){ e1.printStackTrace(); } } } //连接服务器方法 publicvoidconnect(){ try{ socket=newSocket("127.0.0.1",8888); br=newBufferedReader(newInputStreamReader(socket.getInputStream())); bw=newBufferedWriter(newOutputStreamWriter(socket.getOutputStream())); connected=true; newSetNameJTextField(this); }catch(UnknownHostExceptione){ System.out.println("端口错误! "+e.getMessage()); }catch(IOExceptione){ e.printStackTrace(); } } //关闭方法 publicvoiddisConnect(){ if(bw! =null){ try{ bw.close(); bw=null; }catch(IOExceptione1){ e1.printStackTrace(); }finally{ if(br! =null){ try{ br.close(); br=null; }catch(IOExceptione1){ e1.printStackTrace(); }finally{ if(socket! =null){ try{ socket.close(); socket=null; }catch(IOExceptione1){ e1.printStackTrace(); } } } } } } } //client读取操作线程 privateclassClientThreadimplementsRunnable{ Stringstr=null; publicvoidrun(){ try{ while(connected){ while((str=br.readLine())! =null){ Strings=str+" "+sdf.format(newDate())+"\n"; area.setText(area.getText()+s); //设置JTextArea内容过多是聚焦 area.setCaretPosition(area.getText().length()); System.out.println("ServertoClient..."+str); } } }catch(IOExceptione){ System.out.println("Client退出了! "); System.exit(0); } } } //设置名字窗体 privateclassSetNameJTextFieldextendsJFrame{ JButtonbtn_setName=null; Clientc=null; publicSetNameJTextField(finalClientc){ JFrameframe=newJFrame(); this.c=c; frame.setTitle("ScannerUserName..."); frame.setSize(300,130); frame.setLocation(550,250); JPanelpanel=newJPanel(); jname=newJTextField(16); btn_setName=newJButton("OK"); panel.add(newJLabel("UserName: ")); panel.add(jname); panel.add(btn_setName); frame.add(panel); frame.setVisible(true); SetUserNameListenernameListener=newSetUserNameListener(c,frame); btn_setName.addActionListener(nameListener); jname.addActionListener(nameListener); } } privateclassSetUserNameListenerimplementsActionListener{ JFramef=null; Clientclient=null; publicSetUserNameListener(Clientc,JFramef){ this.client=c; this.f=f; } publicvoidactionPerformed(ActionEvente){ try{ name_buf=newBufferedWriter(newOutputStreamWriter(socket.getOutputStream())); userName=jname.getText(); client.setTitle(userName); name_buf.write(userName); name_buf.newLine(); name_buf.flush(); //buf.close(); f.dispose(); }catch(IOExceptione1){ e1.printStackTrace(); } } } } 五、运行结果 六、实习心得和体会 这次的课程设计是简单聊天程序,在平日的生活学习中我们也经常用,比如QQ、MSN等即时通讯软件,所以这个课程设计很有现实意义,做起来也比较感兴趣。 此次编程的一对多聊天工具利用了javasocket套接字编程,由于对于才刚开始学习java语言,由于对java语言的不熟悉,花费了很多时间在对用到的java语言的学习,另外也搜索了一些关于JAVAsocket编程的知识,关于服务器和客户端之间的通信主要借用socket编程,由serversocketsoc=newserversocket(10000)构造对象监视服务器的10000端口,用socket=soc.accept();产生阻塞等待客户端连接,客户端由Socketsoc=newSocket(“172.0.0.1”10000)和服务器产生连接。 由Socket对象得到输入流,并构造相应的BufferedReader对象,由socketd对象得到输出流,服务器从客户端发出的输入流读取信息,编程完时程序不能运行成功,服务器和客户端并不能一对多的聊天,且不能循环,后来询问了学习java的同学,还是没有能找到原因,有在网上搜索一下,也没能有结果,后来我将System.out.println("server: "+is.readLine());从输入流读取服务器信息改为从标准输入读取信息,才运行出正确结果。 通过这次实验,我全面的认识到,计算机网络方面的知识学得不够扎实,不能将知识运用到实践中去。 以后要注意加强。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实现 一个 一对 聊天 程序