失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > java 聊天室之 传送图片文字等功能的实现

java 聊天室之 传送图片文字等功能的实现

时间:2024-01-21 03:45:41

相关推荐

java 聊天室之 传送图片文字等功能的实现

前几日写的一篇简陋之极的java聊天室被各位前辈说是,一塌糊涂,乌烟瘴气,只是简单的实现了需要的功能,并未做到人性化。在下痛定思痛,心想还是先学会显示功能再做美化界面,美化代码的打算!

在奋斗了一天之后终于完成了集图片,文字,直线等功能为一体的群聊天室。先分析代码如下:

关于界面什么的我就不说了,笔者在前面的博客中有提过!直接附上各种功能的实现方法。

首先我们要传送信息,必须要让被传送的对象知道我们传送的是什么东西,所以在传送信息之前,我们首先要确定一个协议,比如说当客户端接收到的第一个int 值为1的时候,它接下来就要再接收4个int值,据此来画一条直线,而我服务器画一条直线的时候可以获得该直线的四个int值,但是在利用IO流发送这四个int值的时候,我首先要先发送一个1,也就是说我每次在要发送一天直线之前就要先发送一个1,当然在客户端读取的时候,我们第一次读取到的是1,就接收四个int。当读完四个int之后并画完一条直线之后我们还要读取数据,如果还是1的话,我们继续上面的操作,如果读取的是2,按照规定的协议,我们就调用相应的方法即可!!!!

现附上服务器发送直线的代码如下,该代码是写在界面类里面的内部类:

Java代码 //鼠标进入事件MouseListenerms=(newMouseListener(){publicvoidmousePressed(MouseEvente){x1=e.getX();y1=e.getY();}publicvoidmouseReleased(MouseEvente){intx2=e.getX();inty2=e.getY();g.drawLine(x1,y1,x2,y2);ChatTools.castbyte(1);ChatTools.castbyte(x1);ChatTools.castbyte(y1);ChatTools.castbyte(x2);ChatTools.castbyte(y2);}publicvoidmouseClicked(MouseEvente){}publicvoidmouseEntered(MouseEvente){}publicvoidmouseExited(MouseEvente){}});jp.addMouseListener(ms);

当然相应的我们也要在客户端定义一个读取数据的方法,首先我们要判断发送过来的是什么东西,我设置的协议是,如果首先读到的是1,接下来就画直线,如果读到的是2,接下来就接收一张图片,如果读到的是4,接下来读到的就是一段文字。该方法是放在客户端的线程中的,并且在线程的Run方法中调用该方法。

并且在每执行完一次操作之后,便再次读取一个int值,再次判断该int值为多少,以便得到下一个执行的指令。

Java代码 publicvoidprocessServer(Socketclient){try{ins=client.getInputStream();OutputStreamout=client.getOutputStream();dis=newDataInputStream(ins);dout=newDataOutputStream(out);intt=dis.readInt();while(true){//如果读到的是1,调用读取线段的方法if(t==1){readline();}//读到的是2则调用接受画面的方法if(t==2){readPic();}//如果读到的是4,则调用接受文字的方法if(t==4){readMsg();}t=dis.readInt();}}catch(Exceptionef){ef.printStackTrace();}}

当判断int值为1的时候,我们就调用画直线的方法,该方法如下

Java代码 //定义一个读取线段的方法publicvoidreadline(){try{intx1=dis.readInt();inty1=dis.readInt();intx2=dis.readInt();inty2=dis.readInt();g.drawLine(x1,y1,x2,y2);}catch(IOExceptione){e.printStackTrace();}}

当然,我们需要在客户端和服务器都要定义相同功能的传送和接收方法。

现在我们再写一个文字的接收方法,首先我们会在文本输入框中输入字符,并获得该文本内容,每当按下发送这个按钮时便调用消息的传送方法,将该消息发送出去!

Java代码 ActionListeneral=(newActionListener(){publicvoidactionPerformed(ActionEvente){Strings=e.getActionCommand();if(s.equals("创建")){Chatservercs=newChatserver(9090,jta,dout,g);cs.start();}//将服务器消息发给每个人if(s.equals("发送")){Stringmsg=jte1.getText();ChatTools.castMsg(msg);jta.append("服务器说:"+msg+"\r\n");jte1.setText("");}

其中ChatTools.castMsg();是一个消息群发的方法,该方法在队列类里面定义的,代码如下

Java代码 //将一个消息发送给所有人ublicstaticvoidcastMsg(Stringstr){ChatTools.castbyte(4);for(inti=0;i<list.size();i++){ServerThreadst=list.get(i);st.sendMs(i+"说:"+str);} Java代码

而sendMsg();则是一个消息的发送方法。该方法如下

Java代码 //将发送消息的代码包装到一个方法中publicvoidsendMs(Stringmsg){try{msg+="\r\n";dout.write(msg.getBytes());//强制输出dout.flush();}catch(Exceptionef){}}

实现字符串传输的重中之重便是读取的方法,我们会首先获得一个为4的int值,然后我们就要调用字符串的读取方法

Java代码 publicvoidreadMsg(){try{brd=newBufferedReader(newInputStreamReader(ins));Stringinput=brd.readLine();jta.append(input+"\r\n");}catch(Exceptionef){}}

我使用的BufferedReader缓冲流,实现整行读取的方式,该方式不会产生乱码,所以还是不错的。

而我今天要重点讲的便是图片从文件中读取和传送的方法。

首先我们要获得图片,再者我们要获取图片的宽度和高度,在循环遍历每个像素点,获取该点的颜色值,接着我们便在画布中调用画线的方法,依次画出每个像素点,并相应的给每个点附上相应的颜色即可。这样一张图片就在自己的画布上显示出来了!代码如下

Java代码 ActionListeneral=(newActionListener(){publicvoidactionPerformed(ActionEvente){Strings=e.getActionCommand();if(s.equals("创建")){Chatservercs=newChatserver(9090,jta,dout,g);cs.start();}//将服务器消息发给每个人if(s.equals("发送")){Stringmsg=jte1.getText();ChatTools.castMsg(msg);jta.append("服务器说:"+msg+"\r\n");jte1.setText("");}if(s.equals("图片")){try{BufferedImageimage=ImageIO.read(newFile("2.jpg"));intm=image.getHeight();intn=image.getWidth();for(inti=0;i<n;i++){for(intj=0;j<m;j++){rgb=image.getRGB(i,j);System.out.println(i);System.out.println(j);Colorcolor=newColor(rgb);g.setColor(color);g.drawLine(i,j,i,j);ChatTools.castbyte(2);ChatTools.castbyte(rgb);ChatTools.castbyte(i);ChatTools.castbyte(j);}}}catch(IOExceptione1){e1.printStackTrace();}

能画出图片,当然我们就能发送图片,我们就能相应的读取图片,在发送图片信息的时候,我们每取出一个点,就能获得该店的颜色,我们就把该点横坐标和纵坐标以及颜色值发送过去。在接收端,我们会首先读到一个为2的int值,然后程序会调用图片的读取方法。方法如下

Java代码 //图片的读取方法publicvoidreadPic(){intrgb;try{rgb=dis.readInt();inti=dis.readInt();intj=dis.readInt();Colorcolor=newColor(rgb);g.setColor(color);g.drawLine(i,j,i,j);}catch(IOExceptione){e.printStackTrace();}}

值此,我们就实现了图片的发送功能了。我的代码也差不多了,至于如果有什么需要改进的地方请各位多多指教,本人是新手,迫切渴望成长,我也知道我的代码可定有很多漏洞,望不吝赐教!!!!!!!!!!!

现在附上具体的代码:服务器的四个类

界面类

Java代码 importjava.awt.Color;importjava.awt.Graphics;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.MouseEvent;importjava.awt.event.MouseListener;importjava.awt.image.BufferedImage;importjava.io.DataOutputStream;importjava.io.File;importjava.io.IOException;importjavax.imageio.ImageIO;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JPanel;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassMainServer{privateintx1;privateinty1;privateGraphicsg;privateDataOutputStreamdout;privateintrgb;publicvoidShowUI(){JFramejf=newJFrame();jf.setTitle("服务器");jf.setSize(600,600);jf.setLayout(null);jf.setDefaultCloseOperation(3);JButtonjb=newJButton("创建");jb.setBounds(0,0,60,30);finalJButtonjm=newJButton("图片");//实例化菜单栏的对象jm.setBounds(70,0,60,30);jf.add(jm);JButtonjb1=newJButton("发送");jb1.setBounds(0,40,60,30);finalJTextFieldjte1=newJTextField(30);jte1.setBounds(70,45,300,20);finalJTextAreajta=newJTextArea(20,30);jta.setBounds(0,80,600,150);finalJPaneljp=newJPanel();jp.setBounds(0,250,600,600);jf.add(jb);jf.add(jb1);jf.add(jte1);jf.add(jta);jf.add(jp);jf.setVisible(true);jp.setBackground(Color.gray);this.g=jp.getGraphics();ActionListeneral=(newActionListener(){publicvoidactionPerformed(ActionEvente){Strings=e.getActionCommand();if(s.equals("创建")){Chatservercs=newChatserver(9090,jta,dout,g);cs.start();}//将服务器消息发给每个人if(s.equals("发送")){Stringmsg=jte1.getText();ChatTools.castMsg(msg);jta.append("服务器说:"+msg+"\r\n");jte1.setText("");}if(s.equals("图片")){try{BufferedImageimage=ImageIO.read(newFile("2.jpg"));intm=image.getHeight();intn=image.getWidth();for(inti=0;i<n;i++){for(intj=0;j<m;j++){rgb=image.getRGB(i,j);System.out.println(i);System.out.println(j);Colorcolor=newColor(rgb);g.setColor(color);g.drawLine(i,j,i,j);ChatTools.castbyte(2);ChatTools.castbyte(rgb);ChatTools.castbyte(i);ChatTools.castbyte(j);}}}catch(IOExceptione1){e1.printStackTrace();}}}});jm.addActionListener(al);jb.addActionListener(al);jb1.addActionListener(al);//鼠标进入事件MouseListenerms=(newMouseListener(){publicvoidmousePressed(MouseEvente){x1=e.getX();y1=e.getY();}publicvoidmouseReleased(MouseEvente){intx2=e.getX();inty2=e.getY();g.drawLine(x1,y1,x2,y2);ChatTools.castbyte(1);ChatTools.castbyte(x1);ChatTools.castbyte(y1);ChatTools.castbyte(x2);ChatTools.castbyte(y2);}publicvoidmouseClicked(MouseEvente){}publicvoidmouseEntered(MouseEvente){}publicvoidmouseExited(MouseEvente){}});jp.addMouseListener(ms);}publicstaticvoidmain(String[]args){MainServerms=newMainServer();ms.ShowUI();}}

处理客户机连接的两个线程类

Java代码 importjava.awt.Graphics;importjava.io.DataOutputStream;.ServerSocket;.Socket;importjavax.swing.JTextArea;publicclassChatserverextendsThread{privateGraphicsg;privateintport;privateJTextAreajta;privateDataOutputStreamdout;//输出流privateServerSocketss;publicChatserver(intport,JTextAreajta,DataOutputStreamdout,Graphicsg){this.port=port;this.jta=jta;this.dout=dout;this.g=g;}publicvoidrun(){setUpServer(port);}//在指定端口上创建一个服务器publicvoidsetUpServer(intport){try{ss=newServerSocket(port);System.out.println("服务器创建成功");//等待客户机连接,并设置成循环等待状态while(true){Socketclient=ss.accept();System.out.println("欢迎进入我的服务器");//启动一个线程去处理该对象ServerThreadst=newServerThread(client,jta,dout,g);st.start();ChatTools.add(st);ChatTools.castMsg("有人上线!!目前在线人数"+ChatTools.getsize());}}catch(Exceptionef){ef.printStackTrace();}}} Java代码 importjava.awt.Color;importjava.awt.Graphics;importjava.io.BufferedReader;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;.Socket;importjavax.swing.JTextArea;publicclassServerThreadextendsThread{privateSocketclient;//线程中处理的客户对象privateDataOutputStreamdout;//输出流privateOutputStreamout;//输出流privateDataInputStreamdis;//privateJTextAreajta;privateBufferedReaderbrd;privateInputStreamins;//创建线程对象时要传入他要处理的连接对象privateGraphicsg;publicServerThread(Socketclient,JTextAreajta,DataOutputStreamdout,Graphicsg){this.client=client;this.jta=jta;this.dout=dout;this.g=g;}publicvoidreadMsg(){try{brd=newBufferedReader(newInputStreamReader(ins));Stringinput=brd.readLine();jta.append("客户说:"+input+"\r\n");ChatTools.castMsg(input);}catch(Exceptionef){}}//将发送消息的代码包装到一个方法中publicvoidsendMs(Stringmsg){try{msg+="\r\n";dout.write(msg.getBytes());//强制输出dout.flush();}catch(Exceptionef){}}publicvoidrun(){//在线程中调用处理链接的方法processChat(this.client);}//处理客户机进入的连接对象publicvoidprocessChat(Socketclient){try{ins=client.getInputStream();out=client.getOutputStream();dis=newDataInputStream(ins);dout=newDataOutputStream(out);intt=dis.readInt();while(true){if(t==1){readline();}if(t==2){readPic();}if(t==4){readMsg();}t=dis.readInt();}}catch(Exceptionef){ef.printStackTrace();}}//发送int型值得方法publicvoidsendbyte(intx1){try{dout.writeInt(x1);dout.flush();}catch(Exceptione){}}//图片的读取方法publicvoidreadPic(){intrgb;try{rgb=dis.readInt();inti=dis.readInt();intj=dis.readInt();Colorcolor=newColor(rgb);g.setColor(color);g.drawLine(i,j,i,j);}catch(IOExceptione){e.printStackTrace();}}//定义一个读取线段的方法publicvoidreadline(){try{intx1=dis.readInt();inty1=dis.readInt();intx2=dis.readInt();inty2=dis.readInt();g.drawLine(x1,y1,x2,y2);}catch(IOExceptione){e.printStackTrace();}}}

一个队列类,用来存储连接进服务器的客户机对象类

Java代码 importjava.util.ArrayList;importjava.util.List;publicclassChatTools{//保存处理线程的队列对象staticList<ServerThread>list=newArrayList<ServerThread>();privateChatTools(){}//不需要创建引类对象,构造器则私有//取得保存保存处理线程对象的队列publicstaticList<ServerThread>getAllthread(){returnlist;}//将一个客户对应的处理线程对象加入到队列中publicstaticvoidadd(ServerThreadst){//通知有人上线了list.add(st);}publicstaticintgetsize(){inti=list.size();returni;}//将一个消息发送给所有人publicstaticvoidcastMsg(Stringstr){ChatTools.castbyte(4);for(inti=0;i<list.size();i++){ServerThreadst=list.get(i);st.sendMs(i+"说:"+str);}}//定义一个字节群发的方法publicstaticvoidcastbyte(intx1){for(inti=0;i<list.size();i++){ServerThreadst=list.get(i);st.sendbyte(x1);}}}

接下来便是客户机的两个类

界面类

Java代码 package多人聊天室客户端;importjava.awt.Color;importjava.awt.Graphics;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.MouseEvent;importjava.awt.event.MouseListener;importjava.awt.image.BufferedImage;importjava.io.File;importjava.io.IOException;importjava.io.InputStream;importjavax.imageio.ImageIO;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JPanel;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassMainchat{privateMainchatThreadmt;privateGraphicsg;privateintx1;privateinty1;privateInputStreamins;privateintrgb;publicvoidShowUI(){JFramejf=newJFrame();jf.setTitle("客户机");jf.setSize(600,500);jf.setLocation(700,0);jf.setLayout(null);jf.setDefaultCloseOperation(3);JButtonjb=newJButton("连接");jb.setBounds(0,0,60,30);finalJButtonjm=newJButton("图片");//实例化菜单栏的对象jm.setBounds(70,0,60,30);jf.add(jm);JButtonjb1=newJButton("发送");jb1.setBounds(0,40,60,30);finalJTextFieldjte1=newJTextField(30);jte1.setBounds(70,45,300,20);finalJTextAreajta=newJTextArea(20,30);jta.setBounds(0,80,600,150);JPaneljp=newJPanel();jp.setBounds(0,250,600,400);jf.add(jb);jf.add(jb1);jf.add(jte1);jf.add(jta);jf.add(jp);jf.setVisible(true);jp.setBackground(Color.gray);this.g=jp.getGraphics();ActionListeneral=(newActionListener(){publicvoidactionPerformed(ActionEvente){Strings=e.getActionCommand();if(s.equals("连接")){try{mt=newMainchatThread("localhost",9090,jta,g,ins);if(mt.runing()){mt.start();}}catch(Exceptione1){e1.printStackTrace();}}//将消息发给别人if(s.equals("发送")){Stringmsg=jte1.getText();jta.append("我说:"+msg+"\r\n");MainchatThread.sendbyte(4);mt.sendMsg(msg);System.out.println("消息已经发送");jte1.setText("");}if(s.equals("图片")){try{BufferedImageimage=ImageIO.read(newFile("2.jpg"));intm=image.getHeight();intn=image.getWidth();for(inti=0;i<n;i++){for(intj=0;j<m;j++){rgb=image.getRGB(i,j);System.out.println(i);System.out.println(j);Colorcolor=newColor(rgb);g.setColor(color);g.drawLine(i,j,i,j);MainchatThread.sendbyte(2);MainchatThread.sendbyte(rgb);MainchatThread.sendbyte(i);MainchatThread.sendbyte(j);}}}catch(IOExceptione1){e1.printStackTrace();}}}});jm.addActionListener(al);jb.addActionListener(al);jb1.addActionListener(al);jf.setVisible(true);MouseListenerms=(newMouseListener(){publicvoidmousePressed(MouseEvente){x1=e.getX();y1=e.getY();System.out.println(x1);}publicvoidmouseReleased(MouseEvente){intx2=e.getX();inty2=e.getY();g.drawLine(x1,y1,x2,y2);MainchatThread.sendbyte(1);MainchatThread.sendbyte(x1);MainchatThread.sendbyte(y1);MainchatThread.sendbyte(x2);MainchatThread.sendbyte(y2);}publicvoidmouseClicked(MouseEvente){}publicvoidmouseEntered(MouseEvente){}publicvoidmouseExited(MouseEvente){}});jp.addMouseListener(ms);}publicstaticvoidmain(String[]args){Mainchatms=newMainchat();ms.ShowUI();}}

线程类,用来运行客户机读取服务器发来的信息

Java代码 package多人聊天室客户端;importjava.awt.Color;importjava.awt.Graphics;importjava.io.BufferedReader;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;.Socket;importjavax.swing.JTextArea;publicclassMainchatThreadextendsThread{privatestaticDataOutputStreamdout;privateInputStreamins;privateBufferedReaderbrd;privateintport;privateStringip;privateJTextAreajta;privateGraphicsg;privateDataInputStreamdis;privateSocketsocket;publicMainchatThread(Stringip,intport,JTextAreajta,Graphicsg,InputStreamins){this.jta=jta;this.ip=ip;this.port=port;this.g=g;this.ins=ins;}publicbooleanruning(){try{socket=newSocket(this.ip,this.port);System.out.println("连接成功");InputStreamins=socket.getInputStream();OutputStreamout=socket.getOutputStream();dis=newDataInputStream(ins);dout=newDataOutputStream(out);returntrue;}catch(Exceptione){e.printStackTrace();}returnfalse;}//图片的读取方法publicvoidreadPic(){intrgb;try{rgb=dis.readInt();inti=dis.readInt();intj=dis.readInt();Colorcolor=newColor(rgb);g.setColor(color);g.drawLine(i,j,i,j);}catch(IOExceptione){e.printStackTrace();}}//发送信息publicvoidsendMsg(Stringmsg){try{msg+="\r\n";dout.write(msg.getBytes());dout.flush();}catch(Exceptionef){}}publicstaticvoidsendbyte(inti){try{dout.writeInt(i);dout.flush();}catch(Exceptionef){}}//读取服务端信息的方法publicvoidreadMsg(){try{brd=newBufferedReader(newInputStreamReader(ins));Stringinput=brd.readLine();jta.append(input+"\r\n");}catch(Exceptionef){}}publicvoidreadline(){try{intx1=dis.readInt();inty1=dis.readInt();intx2=dis.readInt();inty2=dis.readInt();g.drawLine(x1,y1,x2,y2);}catch(Exceptionef){}}publicvoidprocessServer(Socketclient){try{ins=client.getInputStream();OutputStreamout=client.getOutputStream();dis=newDataInputStream(ins);dout=newDataOutputStream(out);intt=dis.readInt();while(true){//如果读到的是1,调用读取线段的方法if(t==1){readline();}//读到的是2则调用接收图片的方法if(t==2){readPic();}//如果读到的是4,则调用接受文字的方法if(t==4){readMsg();}t=dis.readInt();}}catch(Exceptionef){ef.printStackTrace();}}publicvoidrun(){processServer(socket);}}

至此完结!!!

如果觉得《java 聊天室之 传送图片文字等功能的实现》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。