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.TcpClient.java
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 @Override125 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 block152 e.printStackTrace();153 }154 }155 }156 }157 }Qzj.java>_<" 起重機類,這里將大車,小車,勾用類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 }TcpServer.java>_<" 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 };//canvas105 106 @Override107 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 }Draw.java>_<" 負責繪制模擬起重機運動界面,實現模擬起重機的功能~
3、效果展示
>_<" 最終實現客戶端在consoles里輸入相應命令,然后通過TCP把數據傳輸至網絡另一端的服務器,另一端的服務器根據不同的命令做出相應的回應及控制動作~這里運行的時候要先運行服務器部分,是draw文件,不是tcpserver文件,因為總的啟動函數在draw中,客戶端就直接運行但是要在服務器之后~(雖然這是最基本的知識了,但是還是要說一下~),此外每次調試的時候要先關閉客戶端,再關閉服務器,如果一切正常啟動服務器有錯誤,就檢查一下consoles里是否服務器已經關閉(因為每次只能開一個服務器,沒關閉上一個,端口就沒有釋放所以就報錯)
新聞熱點
疑難解答