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

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

时间:2024-04-23 03:40:16

相关推荐

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

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

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

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

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

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

//鼠标进入事件MouseListener ms=(new MouseListener(){public void mousePressed(MouseEvent e){x1=e.getX();y1=e.getY();} public void mouseReleased(MouseEvent e){int x2=e.getX();int y2=e.getY();g.drawLine(x1,y1,x2,y2);ChatTools.castbyte(1);ChatTools.castbyte(x1);ChatTools.castbyte(y1);ChatTools.castbyte(x2);ChatTools.castbyte(y2);}public void mouseClicked(MouseEvent e){}public void mouseEntered(MouseEvent e){}public void mouseExited (MouseEvent e){} });jp.addMouseListener(ms);

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

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

public void processServer(Socket client){try{ins=client.getInputStream();OutputStream out=client.getOutputStream();dis = new DataInputStream(ins);dout=new DataOutputStream(out);int t=dis.readInt();while(true){//如果读到的是1,调用读取线段的方法if(t==1){readline();}//读到的是2则调用接受画面的方法if(t==2){readPic();}//如果读到的是4,则调用接受文字的方法if(t==4){readMsg();}t=dis.readInt();}}catch(Exception ef){ef.printStackTrace();}}

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

//定义一个读取线段的方法public void readline() {try {int x1=dis.readInt();int y1=dis.readInt();int x2=dis.readInt();int y2=dis.readInt();g.drawLine(x1,y1,x2,y2);} catch (IOException e) {e.printStackTrace();}}

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

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

ActionListener al=(new ActionListener(){public void actionPerformed(ActionEvent e){String s=e.getActionCommand();if(s.equals("创建")){Chatserver cs=new Chatserver(9090,jta,dout,g);cs.start();}//将服务器消息发给每个人if(s.equals("发送")){String msg=jte1.getText();ChatTools.castMsg(msg);jta.append("服务器说:"+msg+"\r\n");jte1.setText("");}

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

//将一个消息发送给所有人public static void castMsg(String str){ChatTools.castbyte(4);for(int i=0;i<list.size();i++){ServerThread st=list.get(i);st.sendMs(i+"说:"+str);}}

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

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

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

public void readMsg(){try{brd=new BufferedReader(new InputStreamReader(ins));String input=brd.readLine();jta.append(input +"\r\n");}catch(Exception ef){}}

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

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

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

ActionListener al=(new ActionListener(){public void actionPerformed(ActionEvent e){String s=e.getActionCommand();if(s.equals("创建")){Chatserver cs=new Chatserver(9090,jta,dout,g);cs.start();}//将服务器消息发给每个人if(s.equals("发送")){String msg=jte1.getText();ChatTools.castMsg(msg);jta.append("服务器说:"+msg+"\r\n");jte1.setText("");}if(s.equals("图片")){try {BufferedImage image = ImageIO.read(new File("2.jpg"));int m=image.getHeight();int n=image.getWidth();for(int i=0;i<n;i++){for(int j=0;j<m;j++){rgb=image.getRGB(i,j);System.out.println(i);System.out.println(j);Color color=new Color(rgb);g.setColor(color);g.drawLine(i,j,i,j);ChatTools.castbyte(2);ChatTools.castbyte(rgb);ChatTools.castbyte(i);ChatTools.castbyte(j);}}} catch (IOException e1) {e1.printStackTrace();}

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

//图片的读取方法public void readPic(){int rgb;try {rgb = dis.readInt();int i=dis.readInt();int j=dis.readInt();Color color =new Color(rgb);g.setColor(color);g.drawLine(i,j,i,j);} catch (IOException e) {e.printStackTrace();}}

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

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

界面类

import java.awt.Color;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.image.BufferedImage;import java.io.DataOutputStream;import java.io.File;import java.io.IOException;import javax.imageio.ImageIO;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JTextArea;import javax.swing.JTextField;public class MainServer {private int x1;private int y1;private Graphics g;private DataOutputStream dout;private int rgb;public void ShowUI(){JFrame jf=new JFrame();jf.setTitle(" 服务器");jf.setSize(600,600);jf.setLayout(null);jf.setDefaultCloseOperation(3);JButton jb=new JButton("创建");jb.setBounds(0,0,60,30);final JButton jm = new JButton("图片");// 实例化菜单栏的对象jm.setBounds(70,0,60,30);jf.add(jm);JButton jb1=new JButton("发送");jb1.setBounds(0,40,60,30);final JTextField jte1=new JTextField(30);jte1.setBounds(70,45,300,20);final JTextArea jta=new JTextArea(20,30);jta.setBounds(0,80,600,150);final JPanel jp=new JPanel();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();ActionListener al=(new ActionListener(){public void actionPerformed(ActionEvent e){String s=e.getActionCommand();if(s.equals("创建")){Chatserver cs=new Chatserver(9090,jta,dout,g);cs.start();}//将服务器消息发给每个人if(s.equals("发送")){String msg=jte1.getText();ChatTools.castMsg(msg);jta.append("服务器说:"+msg+"\r\n");jte1.setText("");}if(s.equals("图片")){try {BufferedImage image = ImageIO.read(new File("2.jpg"));int m=image.getHeight();int n=image.getWidth();for(int i=0;i<n;i++){for(int j=0;j<m;j++){rgb=image.getRGB(i,j);System.out.println(i);System.out.println(j);Color color=new Color(rgb);g.setColor(color);g.drawLine(i,j,i,j);ChatTools.castbyte(2);ChatTools.castbyte(rgb);ChatTools.castbyte(i);ChatTools.castbyte(j);}}} catch (IOException e1) {e1.printStackTrace();}}}});jm.addActionListener(al);jb.addActionListener(al);jb1.addActionListener(al);//鼠标进入事件MouseListener ms=(new MouseListener(){public void mousePressed(MouseEvent e){x1=e.getX();y1=e.getY();} public void mouseReleased(MouseEvent e){int x2=e.getX();int y2=e.getY();g.drawLine(x1,y1,x2,y2);ChatTools.castbyte(1);ChatTools.castbyte(x1);ChatTools.castbyte(y1);ChatTools.castbyte(x2);ChatTools.castbyte(y2);}public void mouseClicked(MouseEvent e){}public void mouseEntered(MouseEvent e){}public void mouseExited (MouseEvent e){} });jp.addMouseListener(ms);}public static void main(String[] args){MainServer ms=new MainServer();ms.ShowUI();}}

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

import java.awt.Graphics;import java.io.DataOutputStream;import .ServerSocket;import .Socket;import javax.swing.JTextArea;public class Chatserver extends Thread{private Graphics g;private int port;private JTextArea jta;private DataOutputStream dout;//输出流private ServerSocket ss;public Chatserver(int port,JTextArea jta,DataOutputStream dout,Graphics g){this.port=port;this.jta=jta;this.dout=dout;this.g=g;}public void run(){setUpServer(port);}//在指定端口上创建一个服务器public void setUpServer(int port){try{ss = new ServerSocket(port);System.out.println("服务器创建成功");//等待客户机连接,并设置成循环等待状态while(true){Socket client=ss.accept();System.out.println("欢迎进入我的服务器");//启动一个线程去处理该对象ServerThread st=new ServerThread(client,jta,dout,g);st.start();ChatTools.add(st);ChatTools.castMsg("有人上线!!目前在线人数"+ChatTools.getsize());}}catch(Exception ef){ef.printStackTrace();}}}

import java.awt.Color;import java.awt.Graphics;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import .Socket;import javax.swing.JTextArea;public class ServerThread extends Thread{private Socket client;//线程中处理的客户对象private DataOutputStream dout;//输出流private OutputStream out;//输出流private DataInputStream dis;//private JTextArea jta;private BufferedReader brd;private InputStream ins;//创建线程对象时要传入他要处理的连接对象private Graphics g;public ServerThread(Socket client,JTextArea jta,DataOutputStream dout,Graphics g){this.client=client;this.jta=jta;this.dout=dout;this.g=g;}public void readMsg(){try{brd=new BufferedReader(new InputStreamReader(ins));String input=brd.readLine();jta.append("客户说:"+input +"\r\n");ChatTools.castMsg(input);}catch(Exception ef){}}//将发送消息的代码包装到一个方法中public void sendMs(String msg){try{msg+="\r\n";dout.write(msg.getBytes());//强制输出dout.flush();}catch(Exception ef){}}public void run(){//在线程中 调用处理链接的方法processChat(this.client);}//处理客户机进入的连接对象public void processChat(Socket client){try{ins=client.getInputStream();out=client.getOutputStream();dis = new DataInputStream(ins);dout=new DataOutputStream(out);int t=dis.readInt();while(true){if(t==1){readline();}if(t==2){readPic();}if(t==4){readMsg();}t=dis.readInt();}}catch(Exception ef){ef.printStackTrace();}}//发送int型值得方法public void sendbyte(int x1){try{dout.writeInt(x1);dout.flush();}catch(Exception e){}}//图片的读取方法public void readPic(){int rgb;try {rgb = dis.readInt();int i=dis.readInt();int j=dis.readInt();Color color =new Color(rgb);g.setColor(color);g.drawLine(i,j,i,j);} catch (IOException e) {e.printStackTrace();}}//定义一个读取线段的方法public void readline() {try {int x1=dis.readInt();int y1=dis.readInt();int x2=dis.readInt();int y2=dis.readInt();g.drawLine(x1,y1,x2,y2);} catch (IOException e) {e.printStackTrace();}}}

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

import java.util.ArrayList;import java.util.List;public class ChatTools {//保存处理线程的队列对象static List<ServerThread> list=new ArrayList<ServerThread>();private ChatTools(){}//不需要创建引类对象,构造器则私有//取得保存保存处理线程对象的队列public static List<ServerThread> getAllthread(){return list;}//将一个客户对应的处理线程对象加入到队列中 public static void add(ServerThread st){//通知有人上线了list.add(st);}public static int getsize(){int i=list.size();return i;}//将一个消息发送给所有人public static void castMsg(String str){ChatTools.castbyte(4);for(int i=0;i<list.size();i++){ServerThread st=list.get(i);st.sendMs(i+"说:"+str);}}//定义一个字节群发的方法public static void castbyte(int x1){for(int i=0;i<list.size();i++){ServerThread st=list.get(i);st.sendbyte(x1);}}}

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

界面类

package 多人聊天室客户端;import java.awt.Color;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import java.io.InputStream;import javax.imageio.ImageIO;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JTextArea;import javax.swing.JTextField;public class Mainchat {private MainchatThread mt;private Graphics g;private int x1;private int y1;private InputStream ins;private int rgb;public void ShowUI(){JFrame jf=new JFrame();jf.setTitle(" 客户机");jf.setSize(600,500);jf.setLocation(700,0);jf.setLayout(null);jf.setDefaultCloseOperation(3);JButton jb=new JButton("连接");jb.setBounds(0,0,60,30);final JButton jm = new JButton("图片");// 实例化菜单栏的对象jm.setBounds(70,0,60,30);jf.add(jm);JButton jb1=new JButton("发送");jb1.setBounds(0,40,60,30);final JTextField jte1=new JTextField(30);jte1.setBounds(70,45,300,20);final JTextArea jta=new JTextArea(20,30);jta.setBounds(0,80,600,150);JPanel jp=new JPanel();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();ActionListener al=(new ActionListener(){public void actionPerformed(ActionEvent e){String s=e.getActionCommand();if(s.equals("连接")){try {mt=new MainchatThread("localhost",9090,jta,g,ins);if(mt.runing()){mt.start(); }} catch (Exception e1) {e1.printStackTrace();}}//将消息发给别人if(s.equals("发送")){String msg=jte1.getText();jta.append("我说:"+msg+"\r\n");MainchatThread.sendbyte(4);mt.sendMsg(msg);System.out.println("消息已经发送");jte1.setText("");}if(s.equals("图片")){try {BufferedImage image = ImageIO.read(new File("2.jpg"));int m=image.getHeight();int n=image.getWidth();for(int i=0;i<n;i++){for(int j=0;j<m;j++){rgb=image.getRGB(i,j);System.out.println(i);System.out.println(j);Color color=new Color(rgb);g.setColor(color);g.drawLine(i,j,i,j);MainchatThread.sendbyte(2);MainchatThread.sendbyte(rgb);MainchatThread.sendbyte(i);MainchatThread.sendbyte(j);}}} catch (IOException e1) {e1.printStackTrace();}}}});jm.addActionListener(al);jb.addActionListener(al);jb1.addActionListener(al);jf.setVisible(true);MouseListener ms=(new MouseListener(){public void mousePressed(MouseEvent e){x1=e.getX();y1=e.getY();System.out.println(x1);}public void mouseReleased(MouseEvent e){int x2=e.getX();int y2=e.getY();g.drawLine(x1,y1,x2,y2);MainchatThread.sendbyte(1);MainchatThread.sendbyte(x1);MainchatThread.sendbyte(y1);MainchatThread.sendbyte(x2);MainchatThread.sendbyte(y2);}public void mouseClicked(MouseEvent e){}public void mouseEntered(MouseEvent e){}public void mouseExited (MouseEvent e){} });jp.addMouseListener(ms);} public static void main(String[] args){Mainchat ms=new Mainchat();ms.ShowUI();}}

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

package 多人聊天室客户端;import java.awt.Color;import java.awt.Graphics;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import .Socket;import javax.swing.JTextArea;public class MainchatThread extends Thread{private static DataOutputStream dout;private InputStream ins;private BufferedReader brd;private int port;private String ip;private JTextArea jta;private Graphics g;private DataInputStream dis;private Socket socket;public MainchatThread(String ip,int port,JTextArea jta,Graphics g,InputStream ins){this.jta=jta;this.ip=ip;this.port=port;this.g=g;this.ins=ins;}public boolean runing(){try{socket=new Socket(this.ip,this.port);System.out.println("连接成功");InputStream ins=socket.getInputStream();OutputStream out=socket.getOutputStream();dis=new DataInputStream(ins);dout=new DataOutputStream(out);return true;}catch (Exception e){e.printStackTrace();}return false;}//图片的读取方法public void readPic(){int rgb;try {rgb = dis.readInt();int i=dis.readInt();int j=dis.readInt();Color color =new Color(rgb);g.setColor(color);g.drawLine(i,j,i,j);} catch (IOException e) {e.printStackTrace();}}//发送信息public void sendMsg(String msg){try{msg+="\r\n";dout.write(msg.getBytes());dout.flush();}catch(Exception ef){}}public static void sendbyte(int i){try{dout.writeInt(i);dout.flush();}catch(Exception ef){}}//读取服务端信息的方法public void readMsg(){try{brd=new BufferedReader(new InputStreamReader(ins));String input=brd.readLine();jta.append(input +"\r\n");}catch(Exception ef){}}public void readline(){try{int x1=dis.readInt();int y1=dis.readInt();int x2=dis.readInt();int y2=dis.readInt();g.drawLine(x1,y1,x2,y2);}catch(Exception ef){}}public void processServer(Socket client){try{ins=client.getInputStream();OutputStream out=client.getOutputStream();dis = new DataInputStream(ins);dout=new DataOutputStream(out);int t=dis.readInt();while(true){//如果读到的是1,调用读取线段的方法if(t==1){readline();}//读到的是2则调用接收图片的方法if(t==2){readPic();}//如果读到的是4,则调用接受文字的方法if(t==4){readMsg();}t=dis.readInt();}}catch(Exception ef){ef.printStackTrace();}}public void run(){processServer(socket);}}

至此完结!!!

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

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