前言
主要功能:
类似于腾讯会议。
客户机获取电脑摄像头拍的照片(视频)实时发给服务器。再两端的界面同时显示。客户机上还可以画图,并发给服务器,保存在两端的图形队列中,每次在照片显示后画出队列中的所有图形。
主要思路:
先写一个本地画板,实现画线、圆,并使用cv库获取图片。在写一个网络类,把发送的线、圆、图片的方法封装在里面。并使用Socket在网络类对象里创建一个网络连接。最后再写一个服务器。再实际过程中,并不是先把客户机写完再写服务器。而是两边各先写一个画直线的方法测试一下。一步一步来。
不足之处:
图片发送是先转为二维int数组,在使用writeInt()发送,传输效率不佳,可以尝试一下系统提供的图片IO.
一、准备工作
下载cv库(帮助获取电脑默认相机的开源库)。网址:http://webcam-capture.sarxos.pl/
然后在编译器中导入这三个文件。(解压后在libs文件夹中)
二、代码
1.客户机
客户机主程序代码如下:
package webDrawClient0127;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class DrawBoard extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
// 图形数组
public Shape[] shapeArray;
// 主函数
public static void main(String[] args) {
DrawBoard lu = new DrawBoard();
lu.initUI();
}
// 设置窗口
public void initUI() {
// 设置窗口
// JFrame drawBoard = new JFrame();
this.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
this.setSize(800, 600);
this.setTitle("drawBoard");
// 设置置顶
this.setAlwaysOnTop(true);
// 位置
this.setLocation(200, 100);
// 流式布局
java.awt.FlowLayout flow = new java.awt.FlowLayout();
this.setLayout(flow);
// 设置可见
this.setVisible(true);
// 画笔
Graphics gr = this.getGraphics();
// 画板监听器
DrawMouse mouse = new DrawMouse(gr);
//图像数组
this.shapeArray = mouse.shapeArray;
//监听器线程启动
mouse.start();
this.addMouseListener(mouse);
this.addMouseMotionListener(mouse);
// 边数按钮
//
// 空白
// javax.swing.JLabel kb=new javax.swing.JLabel("");
// java.awt.Dimension dm4 = new java.awt.Dimension(this.getWidth(),
// this.getHeight());
// kb.setPreferredSize(dm4);
// this.add(kb);
// 按钮1
javax.swing.JButton jbu = new javax.swing.JButton("三角形");
jbu.setContentAreaFilled(false);
this.add(jbu);
jbu.addActionListener(mouse);
jbu.setBorderPainted(false);
// 按钮2
javax.swing.JButton jbu2 = new javax.swing.JButton("四边形");
jbu2.setContentAreaFilled(false);
this.add(jbu2);
jbu2.addActionListener(mouse);
jbu2.setBorderPainted(false);
// 按钮3
javax.swing.JButton jbu3 = new javax.swing.JButton("五边形");
jbu3.setContentAreaFilled(false);
this.add(jbu3);
jbu3.addActionListener(mouse);
jbu3.setBorderPainted(false);
// 按钮\\\\\圆
javax.swing.JButton jbuy = new javax.swing.JButton("圆");
jbuy.setContentAreaFilled(false);
this.add(jbuy);
jbuy.addActionListener(mouse);
jbuy.setBorderPainted(false);
// 按钮矩形
javax.swing.JButton jbus = new javax.swing.JButton("矩形");
jbus.setContentAreaFilled(false);
this.add(jbus);
jbus.addActionListener(mouse);
jbus.setBorderPainted(false);
// 按钮铅笔
javax.swing.JButton jbuq = new javax.swing.JButton("铅笔");
jbuq.setContentAreaFilled(false);
this.add(jbuq);
jbuq.addActionListener(mouse);
jbuq.setBorderPainted(false);
// 颜色1
javax.swing.JButton jbu4 = new javax.swing.JButton("颜色1");
// jbu4.setContentAreaFilled (false);
this.add(jbu4);
jbu4.addActionListener(mouse);
jbu4.setBorderPainted(false);
jbu4.setBackground(Color.BLUE);
// 颜色2
javax.swing.JButton jbu5 = new javax.swing.JButton("颜色2");
// jbu5.setContentAreaFilled (false);
this.add(jbu5);
jbu5.addActionListener(mouse);
jbu5.setBorderPainted(false);
jbu5.setBackground(Color.PINK);
// 颜色3
javax.swing.JButton jbu6 = new javax.swing.JButton("颜色3");
// jbu6.setContentAreaFilled (false);
this.add(jbu6);
jbu6.addActionListener(mouse);
jbu6.setBorderPainted(false);
jbu6.setBackground(Color.yellow);
// 重置
javax.swing.JButton re = new javax.swing.JButton("重置");
re.setContentAreaFilled(false);
this.add(re);
re.addActionListener(mouse);
re.setBorderPainted(false);
}
// 重绘图形
public void paint(Graphics g) {
super.paint(g);
// ImageIcon imgIcon = new ImageIcon("D:\\临时\\3img.jpeg");
// //得到Image对象。
// Image img = imgIcon.getImage();
// ImageObserver observer = null;
// g.drawImage(img, 0, 65, this.getWidth(), this.getHeight(), observer);
if(null!=shapeArray) {
for (int i = 0; i < shapeArray.length; i++) {
Shape shp = shapeArray[i];
if (shp != null) {
shp.redraw(g, this.getWidth(), this.getHeight());
}
}
}
}
}
鼠标监听器:
package webDrawClient0127;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Iterator;
import com.github.sarxos.webcam.Webcam;
public class DrawMouse extends Thread implements MouseListener, ActionListener, MouseMotionListener {
// 参数
// 图形数组
public Shape[] shapeArray = new Shape[10000];
private int index = 0;
// 画笔
private Graphics gra;
// 坐标
private int x1, x2, y1, y2;
private Point start, end;
// 多边形边数
private static int n = 0;
// 已画边数记录
private static int m = 0;
// 按钮名字
private String x;
// 铅笔控制变量
private int k = 0;
// 保存初始坐标
private int x0;
private int y0;
// 矩形第一次或第二次点击
private int x12 = 1;
// 静态颜色,初始为BLUE
public static Color color = Color.BLUE;
// 网络模块
Netcon net;
// 构造器,传画笔,设置网络
public DrawMouse(Graphics gr) {
super();
gra = gr;
net = new Netcon(8888);
}
// 传送图像
// 获得画笔
// 设置背景
public void backimage() {
// ImageIcon imgIcon = new ImageIcon("D:\\临时\\3img.jpeg");
// //得到Image对象。
// Image img = imgIcon.getImage();
// ImageObserver observer = null;
// gra.drawImage(img, 0, 65, 2000, 1080, observer);
}
// 画矩形
private void drawsq() {
if (x12 == 1) {
x1 = x2;
y1 = y2;
x12 = 2;
} else {
int x = (x1 + x2 - Math.abs(x1 - x2)) / 2;
int y = (y1 + y2 - Math.abs(y1 - y2)) / 2;
int w = Math.abs(x1 - x2);
int h = Math.abs(y1 - y2);
gra.setColor(color);
gra.drawRect(x, y, w, h);
x12 = 1;
Shape sp = new Shape(this.x, color, x, y, w, h);
shapeArray[index++] = sp;
net.sendsq(color, x, y, w, h);
}
}
// 画圆
private void drawy() {
if (x12 == 1) {
x1 = x2;
y1 = y2;
x12 = 2;
} else {
int x = (x1 + x2 - Math.abs(x1 - x2)) / 2;
int y = (y1 + y2 - Math.abs(y1 - y2)) / 2;
int w = Math.abs(x1 - x2);
int h = Math.abs(y1 - y2);
// 画圆
gra.setColor(color);
gra.fillOval(x, y, w, h);
x12 = 1;
// 存入队列
Shape sp = new Shape(this.x, color, x, y, w, h);
shapeArray[index++] = sp;
// 发送圆
net.sendOvil(color, x, y, w, h);
}
}
// 画多边形
private void draws() {
if (m == 1) {
x0 = x2;
y0 = y2;
x1 = x2;
y1 = y2;
} else {
gra.setColor(color);
gra.drawLine(x1, y1, x2, y2);
// 发送线坐标
net.sendline(color, x1, y1, x2, y2);
Shape sp = new Shape("点线", color, x1, y1, x2, y2);
shapeArray[index++] = sp;
x1 = x2;
y1 = y2;
if (m == n) {
m = 0;
// 停一下画最后一条线
try {
Thread.sleep(300);
} catch (Exception ef) {
}
gra.setColor(color);
net.sendline(color, x1, y1, x2, y2);
gra.drawLine(x0, y0, x2, y2);
Shape spe = new Shape("点线", color, x0, y0, x2, y2);
shapeArray[index++] = spe;
}
}
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
// 鼠标释放时画图
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
x2 = e.getX();
y2 = e.getY();
m++;
if (n != 0)
ms();
}
// ms();判断画图函数
public void ms() {
switch (x) {
case "三角形":
case "四边形":
case "五边形":
draws();
break;
case "圆":
drawy();
break;
case "矩形":
drawsq();
break;
}
}
// 鼠标点击按钮//获得名字//调用选择
public void actionPerformed(ActionEvent e) {
String t = e.getActionCommand();
if (t.equals("颜色1") || t.equals("颜色2") || t.equals("颜色3")) {
colorchose(t);
} else {
x = t;
chose();
}
}
// 颜色选择
public void colorchose(String x) {
if (x.equals("颜色1")) {
colorChose(Color.BLUE);
}
if (x.equals("颜色2")) {
colorChose(Color.PINK);
}
if (x.equals("颜色3")) {
colorChose(Color.yellow);
}
}
// 颜色选择
private void colorChose(Color co) {
color = co;
}
// 画图初始化
public void chose() {
if (x.equals("三角形")) {
k = 0;
n = 3;
m = 0;
backimage();
x12 = 1;
}
if (x.equals("四边形")) {
k = 0;
n = 4;
m = 0;
x12 = 1;
backimage();
}
if (x.equals("五边形")) {
k = 0;
n = 5;
m = 0;
x12 = 1;
backimage();
}
if (x.equals("圆")) {
k = 0;
n = 11;
m = 0;
x12 = 1;
backimage();
}
if (x.equals("矩形")) {
k = 0;
n = 12;
m = 0;
x12 = 1;
backimage();
}
if (x.equals("铅笔")) {
k = 1;
n = 0;
m = 0;
x12 = 1;
backimage();
}
if (x.equals("重置")) {
n = 0;
m = 0;
start = null;
end = null;
x12 = 1;
k = 0;
x = null;
gra.setColor(Color.white);
gra.fillRect(0, 65, 2000, 1080);
gra.setColor(color);
}
}
// 拖动时调用划线
public void mouseDragged(MouseEvent e) {
// 判断是否画铅笔
if (k != 0) {
if (end != null) {
start = end;
}
if (k == 1 || k == 2) {
end = new Point(e.getX(), e.getY());
k++;
}
if (k > 2) {
end = new Point(e.getX(), e.getY());
if (Math.abs(end.x - start.x) < 50) {
// 铅笔划线
paint();
// 发送数据
net.sendPaint(color, start.x, start.y, end.x, end.y);
}
}
}
}
// 铅笔划线
public void paint() {
gra.setColor(color);
gra.drawLine(start.x, start.y, end.x, end.y);
Shape sp = new Shape("点线", color, start.x, start.y, end.x, end.y);
shapeArray[index++] = sp;
System.out.println(index);
}
// 线程获取图像方法
public void run() {
Webcam webcam = Webcam.getDefault();
if (webcam != null) {
webcam.open();
while (true) {
// 获取摄像头
BufferedImage img = webcam.getImage();
int w = img.getWidth();
int h = img.getHeight();
System.out.println("DrawMouse" + "w:" + w + "h:" + h);
// 传输图片
try {
net.sendImg(w, h, img);
gra.drawImage(img, 0, 0, 800, 600, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (null != shapeArray) {
for (int i = 0; i < shapeArray.length; i++) {
Shape shp = shapeArray[i];
if (shp != null) {
shp.redraw(gra, 0, 0);
}
}
}
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
}
} else {
System.out.println("No webcam detected");
}
}
public void mouseMoved(MouseEvent e) {
}
}
网络模块:
package webDrawClient0127;
import java.awt.Color;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
public class Netcon {
/*
* 铅笔为1 圆为2 矩形为3 多边形为4 图片为5
*/
// 客户端网络输入输出流
java.io.InputStream ins;
java.io.OutputStream ous;
java.io.DataInputStream dins;
java.io.DataOutputStream dous;
java.net.Socket client;
// 构造器
public Netcon(int x) {
try {
// 连接服务器
client = new java.net.Socket("127.0.0.1", x);
System.out.println("连结成功~!");
// 获取输入输出流
ins = client.getInputStream();
ous = client.getOutputStream();
// 数据输入输出流
dins = new DataInputStream(ins);
dous = new DataOutputStream(ous);
} catch (Exception e) {
System.out.println("创建网络失败");
}
}
// 发送铅笔坐标
public void sendPaint(Color color, int x1, int y1, int x2, int y2) {
try {
synchronized (dous) {
dous.writeByte(1);// 铅笔为1
// 传输颜色
if (color == Color.BLUE) {
dous.writeByte(1);
}
if (color == Color.PINK) {
dous.writeByte(2);
}
if (color == Color.yellow) {
dous.writeByte(3);
}
dous.writeInt(x1);
dous.writeInt(y1);
dous.writeInt(x2);
dous.writeInt(y2);
}
System.out.println("发送1");
} catch (IOException e) {
e.printStackTrace();
}
}
// 发送圆坐标
public void sendOvil(Color color, int x, int y, int w, int h) {
try {
synchronized (dous) {
dous.writeByte(2);// 圆为2
// 传输颜色
if (color == Color.BLUE) {
dous.writeByte(1);
}
if (color == Color.PINK) {
dous.writeByte(2);
}
if (color == Color.yellow) {
dous.writeByte(3);
}
// 圆心
dous.writeInt(x);
dous.writeInt(y);
// 宽高
dous.writeInt(w);
dous.writeInt(h);
}
System.out.println("发送2");
} catch (IOException e) {
e.printStackTrace();
}
}
// 发送矩形坐标
public void sendsq(Color color, int x, int y, int w, int h) {
try {
synchronized (dous) {
dous.writeByte(3);// 矩形为3
// 传输颜色
if (color == Color.BLUE) {
dous.writeByte(1);
}
if (color == Color.PINK) {
dous.writeByte(2);
}
if (color == Color.yellow) {
dous.writeByte(3);
}
// 圆心
dous.writeInt(x);
dous.writeInt(y);
// 宽高
dous.writeInt(w);
dous.writeInt(h);
}
System.out.println("发送3");
} catch (IOException e) {
e.printStackTrace();
}
}
// 发送多边形坐标
public void sendline(Color color, int x1, int y1, int x2, int y2) {
try {
synchronized (dous) {
dous.writeByte(4);// 多边形为4
// 传输颜色
if (color == Color.BLUE) {
dous.writeByte(1);
}
if (color == Color.PINK) {
dous.writeByte(2);
}
if (color == Color.yellow) {
dous.writeByte(3);
}
dous.writeInt(x1);
dous.writeInt(y1);
dous.writeInt(x2);
dous.writeInt(y2);
}
System.out.println("发送4");
} catch (IOException e) {
e.printStackTrace();
}
}
// 发送图片
public synchronized void sendImg(int w, int h, BufferedImage img) throws IOException {
synchronized (dous) {
// 图片为5
dous.writeByte(5);
// 宽高
dous.writeInt(w);
dous.writeInt(h);
// 图片io
myImageIOwrite(w, h, img, "jpg");
}
// 刷新
// dous.flush();
System.out.println("发送5");
}
private void myImageIOwrite(Integer w, int h, BufferedImage img, String string) throws IOException {
int[][] imgs = new int[w][h];
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
int n = img.getRGB(i, j);// 那点像素点上color的值
imgs[i][j] = n;
}
}
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
int v = imgs[i][j];
dous.writeInt(v);
}
}
}
public static void main(String[] args) {
int m = 123456789;
// System.out.println(m>>8);
Byte[] by = new Byte[4];
for (int i = 0; i < 4; i++) {
by[i] = (byte) (m - ((m >> 8) << 8));
System.out.println(by[i]);
System.out.println(m - ((m >> 8) << 8));
System.out.println(m);
System.out.println(m >> 8 << 8);
m = m >> 8;
// System.out.println(m);
}
// int k=(int)by[0]+((int)by[1])<<8+(int)by[2]<<16+(int)by[3]<<24;
int k = ((int) by[0]) + (((int) by[1]) << 8) + ((int) by[2] << 16) + ((int) by[3] << 24);
System.out.println(k);
}
}
图形类:
package webDrawClient0127;
import java.awt.Color;
import java.awt.Graphics;
public class Shape {
private Color color;
private String name;
public int x1, y1, wt, ht;
//构造器
public Shape(String name, Color color, int x1, int y1, int wt, int ht) {
this.name = name;
this.color = color;
this.x1 = x1;
this.y1 = y1;
this.wt = wt;
this.ht = ht;
}
//画图
public void redraw(Graphics gr, int x, int y) {
switch (name) {
case "矩形":
gr.setColor(color);
gr.drawRect(x1, y1, wt, ht);
break;
// 65+y1*(y-65)/535
case "圆":
gr.setColor(color);
gr.fillOval(x1, y1, wt, ht);
break;
case "点线":
gr.setColor(color);
gr.drawLine(x1, y1, wt, ht);
break;
}
}
}
2.服务器
服务器代码如下:
package webTest0127;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class server extends JFrame {
/*
*
*/
private static final long serialVersionUID = 1L;
// 画笔
Graphics gr;
// 图形保存
private Shape[] shapes = new Shape[10000];
// 记录个数
int index = 0;
// 构造器//窗口设置
public server() {
this.setLocation(1100, 100);
this.setSize(800, 600);
this.setTitle("webDrawServer");
this.setVisible(true);
this.setDefaultCloseOperation(3);
// 设置置顶
this.setAlwaysOnTop(true);
gr = this.getGraphics();
}
// 建立服务器对象//while循环接收
public void creatServer(int port) {
try {
// 建立服务器对象
java.net.ServerSocket myss = new java.net.ServerSocket(port);
System.out.println("服务器创建成功");
// 等待连接
System.out.println("等待");
java.net.Socket client = myss.accept();
System.out.println("连接");
// 输入输出流
java.io.InputStream ins = client.getInputStream();
// java.io.OutputStream ous = client.getOutputStream();
// 数据输入输出流
java.io.DataInputStream dins = new DataInputStream(ins);
//
int t = 0;
while (t != 30) {
int x = dins.readByte();
/*
* 铅笔为1
* 圆为2
* 矩形为3
* 多变形为4
* 图片为5
*/
if (x == 1){
System.out.println("调用: 1");
recevPaint(dins);
}
if (x == 2) {
System.out.println("调用: 2");
recevy(dins);
}
if (x == 3) {
System.out.println("调用: 3");
recevsq(dins);
}
if (x == 4) {
System.out.println("调用: 4");
recevLine(dins);
}
if (x == 5) {
System.out.println("调用: 5 图像");
recevImg(dins);
}
reDraw(gr);
try {
Thread.sleep(30);
} catch (Exception e) {
// TODO: handle exception
}
}
// 通话结束
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//重绘
// 重新绘制涂鸦
private void reDraw(Graphics gr2) {
for (int i = 0; i < index; i++) {
Shape sp = shapes[i];
sp.redraw(gr2, i, i);
}
}
private void recevLine(DataInputStream dins) {
try {
// 传输颜色
Color color = null;
int m = dins.readByte();
if (m == 1) {
color = Color.BLUE;
}
if (m == 2) {
color = Color.PINK;
}
if (m == 3) {
color = Color.yellow;
}
int x1 = dins.readInt();
int y1 = dins.readInt();
int x2 = dins.readInt();
int y2 = dins.readInt();
gr.setColor(color);
gr.drawLine(x1, y1, x2, y2);
Shape sp = new Shape("点线", color, x1, y1, x2, y2);
shapes[index++] = sp;
} catch (IOException e) {
e.printStackTrace();
}
}
private void recevsq(DataInputStream dins) {
try {
// 传输颜色
Color color = null;
int m = dins.readByte();
if (m == 1) {
color = Color.BLUE;
}
if (m == 2) {
color = Color.PINK;
}
if (m == 3) {
color = Color.yellow;
}
int x1 = dins.readInt();
int y1 = dins.readInt();
int w = dins.readInt();
int h = dins.readInt();
gr.setColor(color);
gr.drawRect(x1, y1, w, h);
Shape sp = new Shape("矩形", color, x1, y1, w, h);
shapes[index++] = sp;
} catch (IOException e) {
e.printStackTrace();
}
}
private void recevy(DataInputStream dins) {
try {
// 传输颜色
Color color = null;
int m = dins.readByte();
if (m == 1) {
color = Color.BLUE;
}
if (m == 2) {
color = Color.PINK;
}
if (m == 3) {
color = Color.yellow;
}
int x1 = dins.readInt();
int y1 = dins.readInt();
int w = dins.readInt();
int h = dins.readInt();
gr.setColor(color);
gr.fillOval(x1, y1, w, h);
Shape sp = new Shape("圆", color, x1, y1, w, h);
shapes[index++] = sp;
} catch (IOException e) {
e.printStackTrace();
}
}
//
public void recevPaint(DataInputStream dins) {
try {
// 传输颜色
Color color = null;
int m = dins.readByte();
if (m == 1) {
color = Color.BLUE;
}
if (m == 2) {
color = Color.PINK;
}
if (m == 3) {
color = Color.yellow;
}
int x1 = dins.readInt();
int y1 = dins.readInt();
int x2 = dins.readInt();
int y2 = dins.readInt();
gr.setColor(color);
gr.drawLine(x1, y1, x2, y2);
Shape sp = new Shape("点线", color, x1, y1, x2, y2);
shapes[index++] = sp;
} catch (IOException e) {
e.printStackTrace();
}
}
// 图片
public synchronized void recevImg(DataInputStream dins) throws IOException {
//System.out.println("Server " + "w:" + w + " h:" + h);
try {
//调用ImageIO获得图像
BufferedImage img ;
img=myImageIOread(dins);
System.out.println("Server, w:"+img.getWidth()+ " h:"+img.getHeight());
System.out.println("Server " + "00000000");
//画出图片
gr.drawImage(img, 0, 0, 800, 600, null);
} catch (Exception e) {
System.out.println("Server " + "读取图片失败");
}
}
private BufferedImage myImageIOread(DataInputStream dins) throws IOException {
//读取宽高
int w = dins.readInt();
int h = dins.readInt();
System.out.println("Server, w:"+w+ " h:"+h);
int[][] imgs=new int[w][h];
for(int i=0;i<w;i++){
for(int j=0;j<h;j++){
imgs[i][j]=dins.readInt();
}
}
System.out.println("new img");
BufferedImage img=new BufferedImage(w,h,1);
for(int i=0;i<w;i++){
for(int j=0;j<h;j++){
img.setRGB(i, j, imgs[i][j]);
}
}
return img;
}
//主函数
public static void main(String[] args) {
server ss = new server();
ss.creatServer(8888);
}
}