Java小程序之简易网络画板

时间:2021-11-15 11:57:34

Java小程序之简易网络画板

一、前言:
Java是一门网络编程语言,强大的网络可以让数据进行传送;今天,我们就小试牛刀,看看Java是如何进行网络传输数据的;

二、项目分析:
1、功能需求:
我们前面做个一个小项目--Java画板;现在,假设需要实现这样一个功能,打开两个画板界面,当在一个画板上画东西时,另一个画板能够显示该画板的所画的东西;即网络画板;
2、功能实现:
那么该功能如何实现呢?首先,我们得分析下,如何让我们绘制的图形信息传递到另一个画板上;假设我们绘制的图形是一条直线,绘制这条直线的信息是直线的两端点坐标(两点就可以确定一条直线),我们只需要记录该条直线的连个坐标值,把坐标值的信息发送给服务器,再让服务器转发该信息,在另一个客户端接收到这条信息后,用这条信息绘制一条直线;当然,这里只考虑了直线这一种图形;如果有正方形等其他图形该如何区分呢?这里我们可以自己定义一种协议,协议如下:
图形类型信息+图形信息
1代表直线+直线坐标
2代表正方形+正方形的坐标
......
这样,当客户端接收信息后,先可以判断图形类型,在根据图形类型绘制不同的图形

三、项目实现思路:
1、服务器搭建
2、实现服务器的数据传递
3、画板界面实现
4、画板鼠标监听
5、客户端接收数据后绘制下对应的图形

四、项目源代码:(服务器端和客户端时两个不同的人工程,类似文件压缩有解压缩)

工程结构图:

                      Java小程序之简易网络画板
服务器端:
package Server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Myserver {

public ServerSocket server;

public static ArrayList<ServerThread> list = new ArrayList<ServerThread>();

public void startServer() {

try {
server = new ServerSocket(9090);
System.out.println("服务器已经建立......");
while(true){
Socket socket =server.accept();
System.out.println("有客户端连接进来了......");
ServerThread st = new ServerThread(socket);
st.start();
// System.out.println("线程启动......");
list.add(st);
}
} catch (Exception e) {
e.printStackTrace();
}

}

}


package Server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;

import javax.swing.JOptionPane;

public class ServerThread extends Thread{

public Socket socket;
public DataInputStream dis ;
public DataOutputStream dos;

public ServerThread(Socket socket) {
this.socket=socket;
}

public void run() {
try {
//获取输入输出流
InputStream ins =socket.getInputStream();
OutputStream ous = socket.getOutputStream();
//将字节流包装成数据流
dis=new DataInputStream(ins);
dos=new DataOutputStream(ous);
while(true){
int value=dis.read();
// System.out.println(value);
//服务器转发消息
for (int i = 0; i <Myserver.list.size(); i++) {
ServerThread st =Myserver.list.get(i);
if(st!=this){
st.dos.write(value);
st.dos.flush();
}

}
// System.out.println("服务器已经发送消息");
}
}catch (SocketException e) {
try {
Myserver.list.remove(this);
this.socket.close();
System.out.println("客户端已经退出......");
// JOptionPane.showMessageDialog(null, "客户端退出!");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
}

服务器端主函数
package Server;

public class ServerTest {

public static void main(String[] args) {
Myserver ms = new Myserver();
ms.startServer();
}

}

客户端

package com.huaxin.view;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JFrame;

import com.huaxin.controller.ClientControl;
public class DrawUI extends JFrame{

public Socket socket;
public Graphics2D g;
public ClientControl control;

//界面初始化的socket
public DrawUI() {
try {
socket = new Socket("localhost",9090);
} catch (Exception e) {
e.printStackTrace();
}
}

public void initFrame() {
//设置窗体属性
this.setTitle("网络画板");
this.setSize(600, 500);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setVisible(true);
//拿到窗体的画笔
g = (Graphics2D)this.getGraphics();
g.setColor(Color.RED);
//控制器初始化
control = new ClientControl(g,socket);
//添加鼠标监听
DrawListener listener = new DrawListener(control);
this.addMouseListener(listener);
this.addMouseMotionListener(listener);
//控制器接收数据并处理数据
control.receiveData();
}

}

package com.huaxin.view;

import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import com.huaxin.controller.ClientControl;

public class DrawListener extends MouseAdapter {

public int x1,y1,x2,y2,x4,y4;
public ClientControl control;

//构造函数接受控制器对象
public DrawListener(ClientControl control) {
this.control=control;
}

//监听鼠标按下事件
public void mousePressed(MouseEvent e) {
//获取鼠标按下的坐标值
x1=e.getX();
y1=e.getY();
x4=x1;
y4=y1;
}

//获取鼠标释放的坐标值
// public void mouseReleased(MouseEvent e) {
// x2=e.getX();
// y2=e.getY();
// //当鼠标释放的时候在该画板上绘制一条直线
// control.g.drawLine(x4, y4, x2, y2);
// //第一个1代表图形类型,第二个1代表画笔 粗细
// //将直线信息通过控制器发送给服务器端
// control.sendData(1,x4, y4, x2, y2,1);
// }

//监听鼠标拖动事件(铅笔功能)
public void mouseDragged(MouseEvent e) {
int x3=e.getX();
int y3=e.getY();
control.g.drawLine(x1, y1, x3, y3);
control.sendData(1,x1, y1, x3, y3,1);
x1=x3;
y1=y3;
}
}

package com.huaxin.controller;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ClientControl {

private Socket socket;
public int x1,y1,x2,y2,color;
public byte type,strock;

public Graphics2D g;

public ClientControl(Graphics2D g,Socket socket) {
this.g=g;
this.socket=socket;
}

//不断接受服务器发送过来的信息
public void receiveData(){
new Thread(){
public void run() {
try {
while(true){
//获取输入输出流
InputStream ins = socket.getInputStream();
OutputStream ous=socket.getOutputStream();
//将字节流包装成数据流
DataInputStream dis=new DataInputStream(ins);
DataOutputStream dos= new DataOutputStream(ous);
// System.out.println("kehuduan kaishi dushuju。。。。。。");
//读图形类型
type=dis.readByte();

//读坐标
x1=dis.readInt();
y1=dis.readInt();
x2=dis.readInt();
y2=dis.readInt();
//读粗细
strock=dis.readByte();
//读颜色
color=dis.readInt();
//读完数据之后画图形
// System.out.print("客户端接受数据:");
// System.out.println("type:"+type+"x1:"+x1+"y1:"+y1+"x2:"+y2+"strock:"+strock+"Color:"+type);
drawGra();
}
} catch (Exception e) {
// System.out.println("kehuudan tuichu。。。。。");
e.printStackTrace();
}
};
}.start();
}

//发送图形数据给服务器
public void sendData(int type,int x1,int y1,int x2,int y2,int strock){
try {
//获取输入输出流
InputStream ins = socket.getInputStream();
OutputStream ous=socket.getOutputStream();
//将字节流包装成数据流
DataInputStream dis=new DataInputStream(ins);
DataOutputStream dos= new DataOutputStream(ous);
//写图形类型
dos.writeByte(type);
//写坐标
dos.writeInt(x1);
dos.writeInt(y1);
dos.writeInt(x2);
dos.writeInt(y2);
//写粗细
dos.writeByte(strock);
//写颜色
dos.writeInt(g.getColor().getRGB());
dos.flush();
// System.out.println("type:"+type+"x1:"+x1+"y1:"+y1+"x2:"+y2+"strock:"+strock+"Color:"+type);
// System.out.println("客户端已经发送数据......");
} catch (Exception e) {
e.printStackTrace();
}
}

//绘制图形
public void drawGra() {
g.setColor(new Color(color));
g.setStroke(new BasicStroke(strock));
if(type==1){
g.drawLine(x1, y1, x2, y2);
// System.out.println("hutu 。。。。。");
}
}

}


package com.huaxin.view;

public class ClientTest {

public static void main(String[] args) {
DrawUI ui = new DrawUI();
ui.initFrame();
}
}

五、运行结果:
Java小程序之简易网络画板



六、项目总结:
1、知道了网络中的数据是如何传送和接收的;
2、对Java是一种网络编程语言有了更深的了解;
3、对Java通信等知识有了更深的认知;

我们已经领略了Java作为一门网络编程语言如何编写程序,我们可以用今天学到的知识,看看很多的游戏,可以慢慢了解其中的原理,比如网络五子棋,网络版的你画我猜等;下篇将给大家带来简易版的你画我猜小项目;敬请期待!