用java Socket编写网络白板
最近利用业余时间研究了一下网络白板。
所谓网络白板就是一个客户端在画板上画图的动作原样的重现在其他客户端的画板上。(不光是画出来的图,而且笔画的过程也重现)。实现这个功能需要编写一个画板程序和服务器端程序,其他的就是两者之间的通讯了。
一、服务器端程序的编写
首先利用ServerSocket
在服务器某个端口开启服务,然后等待客户机的连接。一旦有客户机连上后。服务器将开启一个单独的线程与客户机通讯并把客户机的信息记录到一个Hashtable中。方便以后数据的分发。
如下:
package com.canvas;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Hashtable;
public class Server
{
public static void main(String[] args)
{
try
{
ServerSocket
ss = new ServerSocket(8082);
Hashtable
sockets = new Hashtable();
boolean b = true;
while(b)
{
System.out.println("等待客户端的连接......");
Socket s = ss.accept();
System.out.println("客户端"+s.getInetAddress().getHostName()+"连接!");
sockets.put(s.getInetAddress().getHostName(),
s);
new Thread(new Communicate(s,
sockets)).start();
}
ss.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
二、编写画板程序
编写在客户端运行的画板程序相对比较简单,利用BufferedImage记录用户绘制动作,再把BufferedImage绘制出来就可以了。不过要注意的是在画板启动的时候需要连接服务器,并且在每次绘制的时候都需要向服务器发送绘图信息。另外由于要同时绘制其他客户端所绘制的图象,所以在画板启动的时候需要创建一个线程,用来接收服务器发来的其他绘制图象,并绘制它。
代码如下:
package com.canvas;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.net.Socket;
import javax.swing.JFrame;
public class MainFrame extends
JFrame
{
private
ClientUpdateThread clientUpdateThread;
private ClientSend clientSend;
private Canvas canvas;
public MainFrame()
{
try
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(500,500));
setTitle("");
//当服务客户端启动时连接服务器
Socket socket = new Socket("192.168.10.107", 8082);
//设置绘图板
setCanvas(new Canvas(this));
//为客户端创建接收服务器绘图信息的线程
setClientUpdateThread(new ClientUpdateThread(socket,
canvas));
new Thread(getClientUpdateThread()).start();
//设置向服务器发送绘图信息的组件
setClientSend(new ClientSend(socket));
this.add(getCanvas(), BorderLayout.CENTER);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
MainFrame mainFrame = new
MainFrame();
mainFrame.setVisible(true);
mainFrame.pack();
}
public Canvas getCanvas()
{
return canvas;
}
public void
setCanvas(Canvas canvas)
{
this.canvas = canvas;
}
public
ClientUpdateThread getClientUpdateThread()
{
return
clientUpdateThread;
}
public void
setClientUpdateThread(ClientUpdateThread clientUpdateThread)
{
this.clientUpdateThread =
clientUpdateThread;
}
public ClientSend
getClientSend()
{
return clientSend;
}
public void
setClientSend(ClientSend clientSend)
{
this.clientSend =
clientSend;
}
}
package com.canvas;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class Canvas extends JPanel
implements MouseListener, MouseMotionListener
{
//笔的粗细
private float wide;
//画布的背景