[JAVA] 基于TCP的起重机运行模拟器
1、客户端
1 package ClientMain; 2 3 import java.io.DataInputStream; 4 import java.io.DataOutputStream; 5 import java.io.IOException; 6 import java.net.InetAddress; 7 import java.net.Socket; 8 import java.text.SimpleDateFormat; 9 import java.util.Date; 10 import java.util.Scanner; 11 12 public class TcpClient { 13 public static void main(String[] args) throws IOException { 14 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式 15 Socket s = null; 16 DataInputStream DataIn = null; 17 DataOutputStream DataOut = null; 18 try { 19 // s=new Socket(InetAddress.getByName("192.168.1.130"),8000); 20 s = new Socket("localhost", 8000); 21 DataIn = new DataInputStream(s.getInputStream()); 22 DataOut = new DataOutputStream(s.getOutputStream()); 23 System.out.println("连接成功"); 24 @SuppressWarnings("resource") 25 Scanner keyIn = new Scanner(System.in); 26 while (keyIn.hasNext()) { 27 String c = keyIn.nextLine(); 28 System.out.println("输入命令为: " + c); 29 if (c.length() == 0) 30 continue; 31 char inputchar = c.charAt(0);// 输入命令取字符串的第一个 32 switch (inputchar) { 33 case 'a': 34 DataOut.writeByte(inputchar); 35 System.out.println(df.format(new Date()) + " : 执行大车前移命令");// 服务器日志信息 36 System.out.println("服务器返回数据: " + (char) DataIn.readByte()); 37 break;// 大车前移命令 38 case 'b': 39 DataOut.writeByte(inputchar); 40 System.out.println(df.format(new Date()) + " : 执行大车后移命令");// 服务器日志信息 41 System.out.println("服务器返回数据: " + (char) DataIn.readByte()); 42 break;// 大车后移命令 43 case 'c': 44 DataOut.writeByte(inputchar); 45 System.out.println(df.format(new Date()) + " : 执行大车停止命令");// 服务器日志信息 46 System.out.println("服务器返回数据: " + (char) DataIn.readByte()); 47 break;// 大车停止命令 48 case 'd': 49 DataOut.writeByte(inputchar); 50 System.out.println(df.format(new Date()) + " : 执行小车前移命令");// 服务器日志信息 51 System.out.println("服务器返回数据: " + (char) DataIn.readByte()); 52 break;// 小车前移命令 53 case 'e': 54 DataOut.writeByte(inputchar); 55 System.out.println(df.format(new Date()) + " : 执行小车后移命令");// 服务器日志信息 56 System.out.println("服务器返回数据: " + (char) DataIn.readByte()); 57 break;// 小车后移命令 58 case 'f': 59 DataOut.writeByte(inputchar); 60 System.out.println(df.format(new Date()) + " : 执行小车停止命令");// 服务器日志信息 61 System.out.println("服务器返回数据: " + (char) DataIn.readByte()); 62 break;// 小车停止命令 63 case 'g': 64 DataOut.writeByte(inputchar); 65 System.out.println(df.format(new Date()) + " : 执行吊钩上移命令");// 服务器日志信息 66 System.out.println("服务器返回数据: " + (char) DataIn.readByte()); 67 break;// 吊钩上移命令 68 case 'h': 69 DataOut.writeByte(inputchar); 70 System.out.println(df.format(new Date()) + " : 执行吊钩下移命令");// 服务器日志信息 71 System.out.println("服务器返回数据: " + (char) DataIn.readByte()); 72 break;// 吊钩下移命令 73 case 'i': 74 DataOut.writeByte(inputchar); 75 System.out.println(df.format(new Date()) + " : 执行吊钩停止命令");// 服务器日志信息 76 System.out.println("服务器返回数据: " + (char) DataIn.readByte()); 77 break;// 吊钩停止命令 78 case 'j': 79 DataOut.writeByte(inputchar); 80 System.out.println(df.format(new Date()) + " : 执行获取大车位置命令");// 服务器日志信息 81 System.out.println("服务器返回数据: " + (char) DataIn.readByte() 82 + (char) DataIn.readByte() 83 + (char) DataIn.readByte() 84 + (char) DataIn.readByte() 85 + (char) DataIn.readByte() 86 + (char) DataIn.readByte()); 87 break;// 获取大车位置 88 case 'k': 89 DataOut.writeByte(inputchar); 90 System.out.println(df.format(new Date()) + " : 执行获取小车位置命令");// 服务器日志信息 91 System.out.println("服务器返回数据: " + (char) DataIn.readByte() 92 + (char) DataIn.readByte() 93 + (char) DataIn.readByte() 94 + (char) DataIn.readByte() 95 + (char) DataIn.readByte() 96 + (char) DataIn.readByte()); 97 break;// 获取小车位置 98 case 'l': 99 DataOut.writeByte(inputchar); 100 System.out.println(df.format(new Date()) + " : 执行获取吊钩位置命令");// 服务器日志信息 101 System.out.println("服务器返回数据: " + (char) DataIn.readByte() 102 + (char) DataIn.readByte() 103 + (char) DataIn.readByte() 104 + (char) DataIn.readByte() 105 + (char) DataIn.readByte() 106 + (char) DataIn.readByte()); 107 break;// 获取吊钩位置 108 case 'm': 109 DataOut.writeByte(inputchar); 110 System.out.println(df.format(new Date()) + " : 执行获取大车速度命令");// 服务器日志信息 111 System.out.println("服务器返回数据: " + (char) DataIn.readByte() 112 + (char) DataIn.readByte() 113 + (char) DataIn.readByte()); 114 break;// 获取大车速度 115 case 'n': 116 DataOut.writeByte(inputchar); 117 System.out.println(df.format(new Date()) + " : 执行获取小车速度命令");// 服务器日志信息 118 System.out.println("服务器返回数据: " + (char) DataIn.readByte() 119 + (char) DataIn.readByte() 120 + (char) DataIn.readByte()); 121 break;// 获取小车速度 122 case 'o': 123 DataOut.writeByte(inputchar); 124 System.out.println(df.format(new Date()) + " : 执行获取吊钩速度命令");// 服务器日志信息 125 System.out.println("服务器返回数据: " + (char) DataIn.readByte() 126 + (char) DataIn.readByte() 127 + (char) DataIn.readByte()); 128 break;// 获取吊钩速度 129 case 'p': 130 DataOut.writeByte(inputchar); 131 System.out.println(df.format(new Date()) + " : 执行获取重物重量命令");// 服务器日志信息 132 System.out.println("服务器返回数据: " + (char) DataIn.readByte() 133 + (char) DataIn.readByte() 134 + (char) DataIn.readByte() 135 + (char) DataIn.readByte() 136 + (char) DataIn.readByte() 137 + (char) DataIn.readByte()); 138 break;// 获取重物重量 139 case 'q': 140 DataOut.writeByte(inputchar); 141 System.out.println(df.format(new Date()) 142 + " : 执行获取机器本次工作时间命令");// 服务器日志信息 143 System.out.println("服务器返回数据: " + (char) DataIn.readByte() 144 + (char) DataIn.readByte() 145 + (char) DataIn.readByte() 146 + (char) DataIn.readByte() 147 + (char) DataIn.readByte() 148 + (char) DataIn.readByte()); 149 break;// 获取机器本次工作时间 150 case 'r': 151 DataOut.writeByte(inputchar); 152 System.out.println(df.format(new Date()) 153 + " : 执行获取机器总工作次数命令");// 服务器日志信息 154 System.out.println("服务器返回数据: " + (char) DataIn.readByte() 155 + (char) DataIn.readByte() 156 + (char) DataIn.readByte() 157 + (char) DataIn.readByte() 158 + (char) DataIn.readByte() 159 + (char) DataIn.readByte()); 160 break;// 获取机器总工作次数 161 case 's':// [留待以后扩展] 162 DataOut.writeByte(inputchar); 163 System.out.println(df.format(new Date()) 164 + " : 执行获取机器工作状态命令");// 服务器日志信息 165 break;// 获取机器工作状态 166 default: 167 System.out.println(df.format(new Date()) + " : 输入命令有误!");// 服务器日志信息 168 break;// 错误操作 169 } 170 } 171 DataIn.close(); 172 DataOut.close(); 173 s.close(); 174 } catch (IOException e) { 175 // TODO Auto-generated catch block 176 e.printStackTrace(); 177 } 178 DataIn.close(); 179 DataOut.close(); 180 s.close(); 181 } 182 }
2、服务器
1 package ServerMain; 2 3 import java.awt.Graphics2D; 4 5 public class Qzj { 6 public static final int GO = 1, BACK = -1, STOP = 0;// 3种运动状态 7 public Car big, small, hook;// 声明大车,小车和吊钩 8 public int weight;// 称重重量[0-99999kg] 9 public int all_work_times;// 总工作次数[0-99999次] 10 public int this_time;// 本次工作时长[0-99999分钟] 11 public int work_state;// 机器工作状态[留待] 12 13 Qzj() {// 这里偷下懒,一口气把所有参数写进来太麻烦干脆直接在这里修改吧 14 big = new Car(5000, 5, STOP, 0, 10000, 500, 9500, 8);// 大车初始位置为50米处,速度为5dm/s,停止状态,没有警报,轨道100m,左右限位,最大速度为8dm/s 15 small = new Car(100, 2, STOP, 0, 2000, 100, 1900, 5); 16 hook = new Car(0, -2, STOP, 0, 1000, 50, 950, 4); 17 weight = new java.util.Random().nextInt() % 100000; 18 all_work_times = new java.util.Random().nextInt() % 100000; 19 this_time = new java.util.Random().nextInt() % 100000; 20 work_state = 0; 21 22 Thread t1 = new Thread(big); 23 Thread t2 = new Thread(small); 24 Thread t3 = new Thread(hook); 25 26 t1.start(); 27 t2.start(); 28 t3.start(); 29 } 30 31 public class Car implements Runnable { 32 public int position;// 当前车的位置0-99999cm 33 public int speed;// 当前车的速度0-99dm/s 34 public int state;// 当前车的运动状态[GO,BACK,STOP] 35 public int warn;// 当前车是否有限位报警[留待] 36 public int length, limit_Lposition, limit_Rposition, limit_speed;// 轨道长度,左限位,右限位[cm],限速[dm/s] 37 38 Car(int pos, int spe, int sta, int war, int len, int limit_Lpos, 39 int limit_Rpos, int limit_spe) { 40 position = pos; 41 speed = spe; 42 state = sta; 43 warn = war; 44 length = len; 45 limit_Lposition = limit_Lpos; 46 limit_Rposition = limit_Rpos; 47 limit_speed = limit_spe; 48 }// 构造函数 49 50 //将信息显示到屏幕上 51 public void showText(Graphics2D gg,int x,int y) { 52 gg.drawString("$: 实时信息---位置: "+position+" cm, 速度: "+speed+" dm/s, 状态: "+state+" , 警报: "+warn+" , 轨长: "+length+" cm, 左限位: "+limit_Lposition+" cm, 右限位: "+limit_Rposition+" cm, 限速"+limit_speed+" dm/s",x,y); 53 } 54 // //获取参数函数系 55 56 void setPos(int pos) { 57 position = pos; 58 } 59 60 void setSpe(int spe) { 61 speed = spe; 62 } 63 64 void setSta(int sta) { 65 state = sta; 66 } 67 68 void setWar(int war) { 69 warn = war; 70 } 71 72 void setLen(int len) { 73 length = len; 74 } 75 76 void setLimit_Lpos(int limit_Lpos) { 77 limit_Lposition = limit_Lpos; 78 } 79 80 void setLimit_Rpos(int limit_Rpos) { 81 limit_Rposition = limit_Rpos; 82 } 83 84 void setLimit_spe(int limit_spe) { 85 limit_speed = limit_spe; 86 } 87 88 // // 89 90 // //设置参数函数系 91 int getPos() { 92 return position; 93 } 94 95 int getSpe() { 96 return speed; 97 } 98 99 int getSta() { 100 return state; 101 } 102 103 int getWar() { 104 return warn; 105 } 106 107 int getLen() { 108 return length; 109 } 110 111 int getLimit_Lpos() { 112 return limit_Lposition; 113 } 114 115 int getLimit_Rpos() { 116 return limit_Rposition; 117 } 118 119 int getLimit_spe() { 120 return limit_speed; 121 } 122 123 // // 124 @Override 125 public void run() {// 车运动的线程函数 126 while (true) { 127 switch (state) {// 运动处理 128 case GO: 129 position += speed*10;//单位转换,因为速度是dm/s其他的是cm为单位 130 break; 131 case BACK: 132 position -= speed*10;//单位转换 133 break; 134 case STOP: 135 break; 136 default: 137 break; 138 } 139 // 限位报警处理 140 if (position > limit_Rposition) {// 超出右限位,停在右限位 141 position = limit_Rposition; 142 state = STOP; 143 } else if (position < limit_Lposition) {// 超出左限位,停在左限位 144 position = limit_Lposition; 145 state = STOP; 146 } 147 // 等待时间 148 try { 149 Thread.sleep(500); 150 } catch (InterruptedException e) { 151 // TODO Auto-generated catch block 152 e.printStackTrace(); 153 } 154 } 155 } 156 } 157 }
>_<" 起重机类,这里将大车,小车,勾用类Car来实现,然后分别声明(因为他们有相似点);至于起重机其他参数就在QZJ的类里面声明~
1 package ServerMain; 2 3 import java.io.DataInputStream; 4 import java.io.DataOutputStream; 5 import java.io.IOException; 6 import java.net.ServerSocket; 7 import java.net.Socket; 8 import java.text.SimpleDateFormat; 9 import java.util.Date; 10 11 public class TcpServer { 12 13 public static Qzj qzj = new Qzj();// 实例化一个起重机的类 14 public static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式 15 // System.out.println(df.format(new Date()));// new Date()为获取当前系统时间 16 public static ServerSocket server; 17 public static Socket s = null; 18 public static DataOutputStream dataOut = null; 19 public static DataInputStream dataIn = null; 20 21 public TcpServer() throws IOException{ 22 server = new ServerSocket(8000); 23 getandsend mes = new getandsend(); 24 Thread t1 = new Thread(mes); 25 t1.start(); 26 } 27 28 public class getandsend implements Runnable { 29 public void run() { 30 while (true) { 31 try { 32 s = server.accept(); 33 dataOut = new DataOutputStream(s.getOutputStream()); 34 dataIn = new DataInputStream(s.getInputStream()); 35 while (true) { 36 Byte c = dataIn.readByte(); 37 switch (c) { 38 case 'a': 39 dataOut.writeByte('a'); 40 qzj.big.state=Qzj.GO; 41 System.out.println(df.format(new Date()) 42 + " : 执行大车前移命令");// 服务器日志信息 43 break;// 大车前移命令 44 case 'b': 45 dataOut.writeByte('b'); 46 qzj.big.state=Qzj.BACK; 47 System.out.println(df.format(new Date()) 48 + " : 执行大车后移命令");// 服务器日志信息 49 break;// 大车后移命令 50 case 'c': 51 dataOut.writeByte('c'); 52 qzj.big.state=Qzj.STOP; 53 System.out.println(df.format(new Date()) 54 + " : 执行大车停止命令");// 服务器日志信息 55 break;// 大车停止命令 56 case 'd': 57 dataOut.writeByte('d'); 58 qzj.small.state=Qzj.GO; 59 System.out.println(df.format(new Date()) 60 + " : 执行小车前移命令");// 服务器日志信息 61 break;// 小车前移命令 62 case 'e': 63 dataOut.writeByte('e'); 64 qzj.small.state=Qzj.BACK; 65 System.out.println(df.format(new Date()) 66 + " : 执行小车后移命令");// 服务器日志信息 67 break;// 小车后移命令 68 case 'f': 69 dataOut.writeByte('f'); 70 qzj.small.state=Qzj.STOP; 71 System.out.println(df.format(new Date()) 72 + " : 执行小车停止命令");// 服务器日志信息 73 break;// 小车停止命令 74 case 'g': 75 dataOut.writeByte('g'); 76 qzj.hook.state=Qzj.GO; 77 System.out.println(df.format(new Date()) 78 + " : 执行吊钩上移命令");// 服务器日志信息 79 break;// 吊钩上移命令 80 case 'h': 81 dataOut.writeByte('h'); 82 qzj.hook.state=Qzj.BACK; 83 System.out.println(df.format(new Date()) 84 + " : 执行吊钩下移命令");// 服务器日志信息 85 break;// 吊钩下移命令 86 case 'i': 87 dataOut.writeByte('i'); 88 qzj.hook.state=Qzj.STOP; 89 System.out.println(df.format(new Date()) 90 + " : 执行吊钩停止命令");// 服务器日志信息 91 break;// 吊钩停止命令 92 case 'j': 93 sendstring(dataOut, qzj.big.getPos(), 6, 'j'); 94 System.out.println(df.format(new Date()) 95 + " : 执行获取大车位置命令");// 服务器日志信息 96 break;// 获取大车位置 97 case 'k': 98 sendstring(dataOut, qzj.small.getPos(), 6, 'k'); 99 System.out.println(df.format(new Date()) 100 + " : 执行获取小车位置命令");// 服务器日志信息 101 break;// 获取小车位置 102 case 'l': 103 sendstring(dataOut, qzj.hook.getPos(), 6, 'l'); 104 System.out.println(df.format(new Date()) 105 + " : 执行获取吊钩位置命令");// 服务器日志信息 106 break;// 获取吊钩位置 107 case 'm': 108 sendstring(dataOut, qzj.big.getSpe(), 3, 'm'); 109 System.out.println(df.format(new Date()) 110 + " : 执行获取大车速度命令");// 服务器日志信息 111 break;// 获取大车速度 112 case 'n': 113 sendstring(dataOut, qzj.small.getSpe(), 3, 'n'); 114 System.out.println(df.format(new Date()) 115 + " : 执行获取小车速度命令");// 服务器日志信息 116 break;// 获取小车速度 117 case 'o': 118 sendstring(dataOut, qzj.hook.getSpe(), 3, 'o'); 119 System.out.println(df.format(new Date()) 120 + " : 执行获取吊钩速度命令");// 服务器日志信息 121 break;// 获取吊钩速度 122 case 'p': 123 sendstring(dataOut, qzj.weight, 6, 'p'); 124 System.out.println(df.format(new Date()) 125 + " : 执行获取重物重量命令");// 服务器日志信息 126 break;// 获取重物重量 127 case 'q': 128 sendstring(dataOut, qzj.this_time, 6, 'q'); 129 System.out.println(df.format(new Date()) 130 + " : 执行获取机器本次工作时间命令");// 服务器日志信息 131 break;// 获取机器本次工作时间 132 case 'r': 133 sendstring(dataOut, qzj.all_work_times, 6, 'r'); 134 System.out.println(df.format(new Date()) 135 + " : 执行获取机器总工作次数命令");// 服务器日志信息 136 break;// 获取机器总工作次数 137 case 's':// [留待以后扩展] 138 sendstring(dataOut, qzj.work_state, 6, 's'); 139 System.out.println(df.format(new Date()) 140 + " : 执行获取机器工作状态命令");// 服务器日志信息 141 break;// 获取机器工作状态 142 default: 143 break;// 错误操作 144 } 145 } 146 } catch (IOException e) { 147 }finally{ 148 try { 149 dataOut.close(); 150 dataIn.close(); 151 s.close(); 152 } catch (IOException e) { 153 e.printStackTrace(); 154 } 155 } 156 } 157 } 158 } 159 160 // 将int类的data转换为i-1位字符串并加上c结尾发送出去函数 161 private static void sendstring(DataOutputStream dataOut, int data, int i, 162 char c) throws IOException { 163 switch (i) { 164 case 6: 165 dataOut.writeByte((char) (data / 10000 + '0')); 166 data %= 10000; 167 case 5: 168 dataOut.writeByte((char) (data / 1000 + '0')); 169 data %= 1000; 170 case 4: 171 dataOut.writeByte((char) (data / 100 + '0')); 172 data %= 100; 173 case 3: 174 dataOut.writeByte((char) (data / 10 + '0')); 175 data %= 10; 176 case 2: 177 dataOut.writeByte((char) (data + '0')); 178 case 1: 179 dataOut.writeByte(c); 180 } 181 } 182 183 public static void main(String[] args) throws IOException { 184 new TcpServer(); 185 } 186 }
>_<" TCP服务器,负责接收客户端命令和处理命令~
1 package ServerMain; 2 3 4 import javax.swing.*; 5 import java.awt.*; 6 import java.io.IOException; 7 8 9 final class Draw extends JFrame implements Runnable { 10 11 public static TcpServer tcp; 12 13 Draw() throws HeadlessException, IOException { 14 super(); 15 Container container = getContentPane(); 16 container.add(canvas, BorderLayout.CENTER);//把canvas加入中间 17 pack(); 18 tcp=new TcpServer();//使命并实例化一个TCP服务器并启动 19 } 20 21 private final static JComponent canvas = new JComponent() { 22 protected void paintComponent(Graphics g) { 23 super.paintComponent(g); 24 drawQZJ(g); 25 drawText(g); 26 } 27 28 //http://www.weixueyuan.net/view/6074.html Graphics资料 29 //绘制起重机3维图像 30 private int a=10,b=90,wid=600,len=380;//矩形框的位置和大小 31 public void drawQZJ(Graphics g){ 32 Graphics2D gg=(Graphics2D)g; 33 gg.setColor(Color.BLUE); 34 gg.fillRect(0 , 0 , 800 , 480); 35 gg.setColor(Color.YELLOW); 36 gg.fillRect(a, b , wid, len); 37 gg.setColor(Color.BLACK); 38 gg.drawRect(a, b , wid, len); 39 Stroke stroke=new BasicStroke(2.0f);//设置线宽为2.0 40 gg.setStroke(stroke); 41 gg.setColor(Color.BLACK); 42 //最长横梁边距为15,间距为100 43 gg.drawLine(a+15, b+15,wid+a-15, b+15); 44 gg.drawLine(a+15, b+115,wid+a-15, b+115); 45 //画大车,将位置经过比例运算展现,这里位置默认为大车中间位置,所以前后伸长25 46 gg.drawLine(a+15-25+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(), b+5,a+15-25+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(), b+125); 47 gg.drawLine(a+15+25+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(), b+5,a+15+25+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(), b+125); 48 //画小车 49 gg.setColor(Color.RED); 50 gg.drawLine(a+15-25+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen()-10, b+15+tcp.qzj.small.getPos()*100/tcp.qzj.small.getLen(),a+15+25+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen()+10, b+15+tcp.qzj.small.getPos()*100/tcp.qzj.small.getLen()); 51 //画勾 52 gg.setColor(Color.BLACK); 53 gg.drawLine(a+15,b+175,wid+a-15,b+175);//横轨 54 stroke=new BasicStroke(1.0f);//设置线宽为1.0 55 gg.setStroke(stroke); 56 gg.drawRect(a+15-4+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(),b+175-4,8,6);//滑块8X6 57 gg.drawLine(a+15+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(),b+175+2,a+15+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(),tcp.qzj.hook.getPos()*170/tcp.qzj.hook.getLen()+b+175+2);//中间的线 58 gg.fillRect(a+15-3+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(),tcp.qzj.hook.getPos()*170/tcp.qzj.hook.getLen()+b+175+2,7,6);//下面的小方块7X6 59 gg.drawLine(a+15+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(),tcp.qzj.hook.getPos()*170/tcp.qzj.hook.getLen()+b+175+2+6,a+15+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(),tcp.qzj.hook.getPos()*170/tcp.qzj.hook.getLen()+b+175+2+6+3);//下面是画最下面的勾 60 gg.drawRect(a+15-6+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(),tcp.qzj.hook.getPos()*170/tcp.qzj.hook.getLen()+b+175+2+6+3,12,6);//负载12X6 61 gg.setColor(Color.YELLOW); 62 gg.fillRect(a+15-6-1+tcp.qzj.big.getPos()*(wid-30)/tcp.qzj.big.getLen(),tcp.qzj.hook.getPos()*170/tcp.qzj.hook.getLen()+b+175+2+6+3-1,7,4);//画一个黄色的矩形将上面的矩形变成一个勾 63 64 } 65 66 //显示起重机信息 67 private void drawText(Graphics g) { 68 Graphics2D gg=(Graphics2D)g; 69 gg.setColor(Color.BLACK); 70 //右边上部分显示起重机的整体运动实时参数 71 gg.drawString("$ 称重重量: "+tcp.qzj.weight+" [kg]",620,100);//weight 72 gg.drawString("$ 总工作次数: "+tcp.qzj.all_work_times+" [次]",620,120);//all_work_times 73 gg.drawString("$ 本次工作时长: "+tcp.qzj.this_time+" [分钟]",620,140);//this_time 74 gg.drawString("$ 机器工作状态: "+tcp.qzj.work_state+" [留待]",620,160);//work_state 75 gg.drawLine(620, 165, 760, 165); 76 //右下部分显示客户端TCP发送过来的控制命令 77 gg.drawString("$ 大车前移命令: a",620,180); 78 gg.drawString("$ 大车后移命令: b",620,195); 79 gg.drawString("$ 大车停止命令: c",620,210); 80 gg.drawString("$ 小车前移命令: d",620,225); 81 gg.drawString("$ 小车后移命令: e",620,240); 82 gg.drawString("$ 小车停止命令: f",620,255); 83 gg.drawString("$ 吊钩上移命令: g",620,270); 84 gg.drawString("$ 吊钩下移命令: h",620,285); 85 gg.drawString("$ 吊钩停止命令: i",620,300); 86 gg.drawString("$ 获取大车位置: j",620,315); 87 gg.drawString("$ 获取小车位置: k",620,330); 88 gg.drawString("$ 获取吊钩位置: l",620,345); 89 gg.drawString("$ 获取大车速度: m",620,360); 90 gg.drawString("$ 获取小车速度: n",620,375); 91 gg.drawString("$ 获取吊钩速度: o",620,390); 92 gg.drawString("$ 获取重物重量: p",620,405); 93 gg.drawString("$ 本次工作时间: q",620,420); 94 gg.drawString("$ 总的工作次数: r",620,435); 95 gg.drawString("$ 获取工作状态: s",620,450); 96 //上面一部分显示实时信息 97 gg.drawString("$----嵌入式操作系统Java模拟机,第1.0版,2014-9-18-3:15----$",230,20);//标题 98 tcp.qzj.big.showText(gg, 10, 50); 99 tcp.qzj.small.showText(gg, 10, 65); 100 tcp.qzj.hook.showText(gg, 10, 80); 101 102 } 103 104 };//canvas 105 106 @Override 107 public void run() {//每隔一定时间进行绘制 108 while(true){ 109 canvas.repaint(); 110 try { 111 Thread.sleep(100); 112 }catch (Exception e){} 113 } 114 } 115 116 public static void main(String[] args) throws IOException { 117 //绘图窗口实例化并启动刷新进程 118 Draw show=new Draw(); 119 show.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 120 show.setSize(800,518); 121 show.setVisible(true); 122 Thread t2 = new Thread(show); 123 t2.start(); 124 } 125 }
>_<" 负责绘制模拟起重机运动界面,实现模拟起重机的功能~
3、效果展示
>_<" 最终实现客户端在consoles里输入相应命令,然后通过TCP把数据传输至网络另一端的服务器,另一端的服务器根据不同的命令做出相应的回应及控制动作~这里运行的时候要先运行服务器部分,是draw文件,不是tcpserver文件,因为总的启动函数在draw中,客户端就直接运行但是要在服务器之后~(虽然这是最基本的知识了,但是还是要说一下~),此外每次调试的时候要先关闭客户端,再关闭服务器,如果一切正常启动服务器有错误,就检查一下consoles里是否服务器已经关闭(因为每次只能开一个服务器,没关闭上一个,端口就没有释放所以就报错)
[图1 服务器模拟端界面]
[图2 客户端Console部分]
[图3 服务器端consoles部分]
4、通信协议