美文网首页IoT-Arduino
Java socket编程一次奇怪的bug

Java socket编程一次奇怪的bug

作者: Upstreamzy | 来源:发表于2018-07-16 14:39 被阅读2次

    近些天以来一直在写些arduino,这个东西总是遭遇一些很奇怪的bug。
    就在前几天我们的我们遭遇了一个这样的bug
    我们是要用arduino和pc端通信采用的是TCP/IP协议,arduino做客户端pc做server端,arduino用它自己的语言那种类似于c++的语言,然后pc端用的是Java

    这是arduino上面的代码

    //这是arduino上的代码
    #include "Keypad.h" 
    #include "PN532.h"
    #include "TaskScheduler.h"  //包含此头文件,才能使用调度器
    #define box1 15
    String correct_Box = "";
    
    char customKey = ' ';//keypad                                                                                                
    char c = ' ';                                                                                                               
    String padkey = ""; 
    
    String comdata = "";//RFID
    
    const byte ROWS = 4; //four rows
    const byte COLS = 4; //four columns
    //define the cymbols on the buttons of the keypads
    char hexaKeys[ROWS][COLS] = {                                                                                 
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
    };
    byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad                                  
    byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad                            
    
    //initialize an instance of class NewKeypad
    Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
    
    
    uint32_t id=0;//rfid
    #define SCK 10
    #define MOSI 11
    #define SS 12
    #define MISO 13
    PN532 nfc(SCK, MISO, MOSI, SS);
    
    
    void setup(){
      pinMode(box1,OUTPUT);                                                                                           
      digitalWrite(box1, HIGH);                                                                                  
      
      Serial.begin(115200);
    
      //RFID的代码部分
      nfc.begin();
      uint32_t versiondata = nfc.getFirmwareVersion();
      if (! versiondata) {
        Serial.print("Didn't find PN53x board");
    //    while (1); // halt
      }
    //Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
    //Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
    //Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
    //Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX);
    
    }
    
    void loop(){
      while(Serial.read()>0){};
      
      c = customKeypad.getKey();  
                                                                         
      // 根据映射后的值进行不同处理:
      switch (c) {
        case 'A'://rfid认证
          Serial.print("A");
    //      Serial.flush();
          get_rfid();
          get_correct_Box();
          open_box();
          break;
        case 'B'://密码认证
          Serial.print("B");
    //      Serial.flush();
          get_keyPad();
          get_correct_Box();
          open_box();
          break;
        case 'C':  
          break;    
        case 'D':    
          
          break;
      }
    }
    
    void get_keyPad(){
    //  customKey = "";
      // 根据映射后的值进行不同处理:
      while(padkey.length() != 4){                                                                                   
        customKey = customKeypad.getKey();
    //    Serial.print("hello");
        switch (customKey) {
          case '*':
    //        Serial.println("Start:");
            break;
          case '#':
    //        Serial.println("End:");
            break;
          case ' ':
    //        Serial.println("Empty");
            break;
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '8':
          case '9':
          case '0':
            padkey += customKey;                                                                                          
            break;
          default:
            break;
      }
     }
      padkey="2222";
    //   Serial.println("End:");
       Serial.print("#"+padkey); 
    //   Serial.flush();
       delay(10);
       delay(10);
       delay(10);
       delay(10);
       delay(10);
    }
    
    void get_rfid(){
      while(id==0){
      
      // configure board to read RFID tags and cards
        nfc.SAMConfig();
        // look for MiFare type cards
        id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
        if (id!=0) {
    //      Serial.print("rfid_ID:"); 
    //      Serial.println(id);
          String str = "&";
          str.concat(id);
    //      Serial.print(str);
    //      Serial.flush();
    //      str.remove(str.length() - 1);
          Serial.print(str);
    //      Serial.flush();
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
    //      id = 0;
        }
    //    id = 0;
      }
      id = 0;
    }
    
    // returns -1 if failed, otherwise returns ID #
    void get_correct_Box(){
      while(Serial.available() > 0)                                                                              //??串口缓存区的问题???
      {
        char c = char(Serial.read());
        if(c != 'e')
          correct_Box += c;
    //    delay(2);
      }
      delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         if(correct_Box != "")
          Serial.print(correct_Box + "++");
      delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
    //  if(sizeof(correct_Box) > 0)
    //    Serial.println("#" + correct_Box);
    //    Serial.println("*");
     }
    
    
      
    void open_box(){ 
    //  Serial.println("*" + correct_Box);
    //  Serial.println("*");
    //    Serial.println(correct_Box.charAt(0));
        if(correct_Box.charAt(0) == '1') {
          Serial.println("box1,LOW");
          delay(10);
          Serial.println("box1,HIGH");
          delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
    //      Serial.flush();
        digitalWrite(box1, LOW);
            delay(50);
            digitalWrite(box1, HIGH);
       }
       padkey = ""; 
       correct_Box = "";                                                                                                  
    }
    

    WiFi模块的代码

    //这是WiFi模块上面的代码
    #include <ESP8266WiFi.h>
      
    #define relay1 2
    const char *ssid     = "root";//这里是我的wifi,你使用时修改为你要连接的wifi ssid
    const char *password = "1234567890";//你要连接的wifi密码
    const char *host = "192.168.43.230";//修改为手机的的tcpServer服务端的IP地址,即手机在路由器上的ip
    WiFiClient client;
    const int tcpPort = 9090;//修改为你建立的Server服务端的端口号
      
      
    void setup()
    {   
        pinMode(relay1,OUTPUT);
        Serial.begin(115200);
        delay(10);
        Serial.println();
        Serial.println();
        Serial.print("Connecting to ");
        Serial.println(ssid);
      
        WiFi.begin(ssid, password);
      
        while (WiFi.status() != WL_CONNECTED)//WiFi.status() ,这个函数是wifi连接状态,返回wifi链接状态
                                             //这里就不一一赘述它返回的数据了,有兴趣的到ESP8266WiFi.cpp中查看
        {
            delay(500);
            Serial.print("aaaaaaa");
        }//如果没有连通向串口发送.....
      
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());//WiFi.localIP()返回8266获得的ip地址
    }
      
      
    void loop()
    {
        while (!client.connected())//几个非连接的异常处理
        {
            if (!client.connect(host, tcpPort))
            {
                Serial.println("connection....");
                //client.stop();
                delay(500);
      
            }
        }
    while (client.available())//改动的就这里啦,无线读取到的数据转发到到串口
        {
            uint8_t c = client.read();
            Serial.write(c);
            
        }
     
     
        if (Serial.available())//串口读取到的转发到wifi,因为串口是一位一位的发送所以在这里缓存完再发送
        {
            size_t counti = Serial.available();
            uint8_t sbuf[counti];
            Serial.readBytes(sbuf, counti);
            client.write(sbuf, counti);
     
        }
    }
    

    上面这个WiFi模块的代码很明显就是socket编程的操作,这个操作很简单就是读取网络中的数据然后在发给串口。
    然后对于arduino上面的代码我们只关注它的

    Serial.print();
    

    因为arduino板子和WiFi模块就是通过rx和tx接口来和进行通信的,然后rx和tx就是IO嘛。
    差不多arduino的IO流程是这样的:


    arduino.jpg

    Java代码

    while(true){
    //                System.out.print("");
    //                    System.out.print("");
                        int count = 0;
                        byte[] inDatas = null;
                        try {
                            while (count == 0) {
                                count = in.available();
                            }
                            inDatas = new byte[count];
                            System.out.print("");
                            in.read(inDatas);
                            msg = new String(inDatas, "gb2312");
                            System.out.println(msg);
    //                        out.write("1".getBytes());
                            switch (msg.charAt(0)) {
                                case '#':
    //                                System.out.println("*");
                                    ResultSet queryResultSet = statement.executeQuery("SELECT * FROM cabinet WHERE keypassword=" + "'" + msg + "'");
                                    System.out.println("SELECT * FROM cabinet WHERE keypassword=" + "'" + msg + "'");
                                    if (queryResultSet.next()) {
                                        String keypassword = queryResultSet.getString("keypassword");
                                        String x = queryResultSet.getString("cabinet_id");
                                        System.out.println(x);
                                        out.write(x.getBytes());
                                        list.remove((Integer) Integer.parseInt(x));
    //                                    System.out.println(Integer.getInteger(x));
    //                                    System.out.println(list);
                                        statement.execute("DELETE FROM cabinet WHERE cabinet_id=" + "'" + x + "'");
                                    } else {
                                        ResultSet queryResultSetJudgeTable = statement.executeQuery("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
                                                "(cabinet.keypassword=student.keypassword OR \n" +
                                                "cabinet.rfid=student.rfid OR cabinet.fingerprint=student.fingerprint) AND student.keypassword=" + "'" + msg + "'");
                                        System.out.println("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
                                                "(cabinet.keypassword=student.keypassword OR \n" +
                                                "cabinet.rfid=student.rfid OR cabinet.fingerprint=student.fingerprint) AND student.keypassword=" + "'" + msg + "'");
    //                                    System.out.println(queryResultSetJudgeTable.next());
    //                                    System.out.println(queryResultSetJudgeTable.getString("cabinet_id"));
                                        if (queryResultSetJudgeTable.next()) {
                                            String x = queryResultSetJudgeTable.getString("cabinet_id");
                                            System.out.println(x);
                                            statement.execute("UPDATE cabinet SET keypassword=" + "'" +  msg + "'" + " WHERE cabinet_id=" + "'" +
                                                    x + "'");
                                            System.out.println("UPDATE cabinet SET keypassword=" + "'" +  msg + "'" + " WHERE cabinet_id=" + "'" +
                                                    x + "'");
                                        } else {
                                            Random rand = new Random();
                                        int x = 0;
                                        int i1 = 0;
                                        while (true) {
                                            x = rand.nextInt(1) + 1;
    //                                        System.out.println("x=" + x);
                                            if (!list.contains(x) && x != 0) {  // 2  3
    //                                            out.write(x);
    //                                            System.out.println("x=" + x);
    //                                            treeSetCabinet.add(x);
                                                list.add(x);
    //                                            System.out.println(treeSetCabinet+"treeSetCabi");
                                                break;
                                            }
                                            if (i1 > 5)
                                                break;
                                            i1++;
                                        }
                                            statement.execute("INSERT INTO cabinet(cabinet_id, keypassword) VALUES " + "('" + x + "','" + msg + "')");
                                            out.write(((Integer)x).toString().getBytes());
                                            Thread.sleep(1000);
                                            out.write(((Integer)x).toString().getBytes());
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                        }
                                    }
                                    break;
                                case '&':
                                    ResultSet queryResultSet1 = statement.executeQuery("SELECT * FROM cabinet WHERE rfid=" + "'" + msg + "'");
                                    System.out.println("SELECT * FROM cabinet WHERE rfid=" + "'" + msg + "'");
                                    if (queryResultSet1.next()) {
    //                                    out.write(queryResultSet1.getString("cabinet_id").getBytes());
                                        String rfid = queryResultSet1.getString("rfid");
                                        String x = queryResultSet1.getString("cabinet_id");
                                        System.out.println(x);
                                        out.write(x.getBytes());
                                        list.remove((Integer) Integer.parseInt(x));
                                        System.out.println(x.equals("1") || x.equals("2"));
    //                                    System.out.println(Integer.getInteger(x));
    //                                    System.out.println(list);
                                        statement.execute("DELETE FROM cabinet WHERE cabinet_id=" + "'" + x + "'");
    //                                    System.out.println("*");
                                        System.out.println("DELETE FROM cabinet WHERE cabinet_id=" + "'" + x + "'");
                                    } else {
                                        ResultSet queryResultSetJudgeTable = statement.executeQuery("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
                                                "(cabinet.keypassword=student.keypassword OR \n" +
                                                "cabinet.rfid=student.rfid OR cabinet.fingerprint=student.fingerprint) AND student.rfid=" + "'" + msg + "'");
                                        System.out.println("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
                                                "(cabinet.keypassword=student.keypassword OR \n" +
                                                "cabinet.rfid=student.keypassword OR cabinet.fingerprint=student.fingerprint) AND student.keypassword" + "'" + msg + "'");
                                        if (queryResultSetJudgeTable.next()) {
                                            String x = queryResultSetJudgeTable.getString("cabinet_id");
                                            statement.execute("UPDATE cabinet SET rfid=" + "'" +  msg + "'" + " WHERE cabinet_id=" + "'" +
                                                    x + "'");
                                            System.out.println("UPDATE cabinet SET rfid=" + "'" +  msg + "'" + " WHERE cabinet_id=" + "'" +
                                                    x + "'");
                                        } else {
                                            Random rand = new Random();
                                            int x = 0;
                                            int i1 = 0;
                                            while (true) {
                                                x = rand.nextInt(1) + 1;
    //                                        System.out.println("x=" + x);
                                                if (!list.contains(x) && x != 0) {  // 2  3
    //                                            out.write(x);
    //                                            System.out.println("x=" + x);
    //                                            treeSetCabinet.add(x);
                                                    list.add(x);
    //                                            System.out.println(treeSetCabinet+"treeSetCabi");
                                                    break;
                                                }
    
                                                if (i1 > 5)
                                                    break;
                                                i1++;
                                            }
                                            statement.execute("INSERT INTO cabinet(cabinet_id, rfid) VALUES " + "('" + x + "','" + msg + "')");
    //                                        System.out.print("");
    
                                            out.write(((Integer)x).toString().getBytes());
                                            Thread.sleep(2000);
                                            out.write(((Integer)x).toString().getBytes());
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                            for (int i = 0; i < 100; i++) {
                                                out.write(((Integer)x).toString().getBytes());
                                            }
                                            System.out.println(x);
                                            System.out.println(((Integer) x).toString().getBytes());
                                            System.out.println(((Integer)x).toString());
                                            System.out.println(((Integer)x).toString().equals("1"));
                                            System.out.println(((Integer)x).toString().equals("2"));
    //                                        out.write(((Integer) 1).toString().getBytes());
                                        }
                                    }
                                    break;
                                case '*':
                                    ResultSet queryResultSet2 = statement.executeQuery("SELECT * FROM cabinet WHERE fingerprint=" + "'" + msg + "'");
                                    System.out.println("SELECT * FROM cabinet WHERE fingerprint=" + "'" + msg + "'");
                                    if (queryResultSet2.next()) {
                                        String rfid = queryResultSet2.getString("fingerprint");
                                        String x = queryResultSet2.getString("cabinet_id");
                                        out.write(x.getBytes());
                                        list.remove((Integer) Integer.parseInt(x));
    //                                    System.out.println(Integer.getInteger(x));
    //                                    System.out.println(list);
                                        statement.execute("DELETE FROM cabinet WHERE cabinet_id=" + "'" + x + "'");;
                                    } else {
                                        ResultSet queryResultSetJudgeTable = statement.executeQuery("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
                                                "(cabinet.keypassword=student.keypassword OR \n" +
                                                "cabinet.rfid=student.rfid OR cabinet.fingerprint=student.fingerprint) AND student.fingerprint=" + "'" + msg + "'");
                                        System.out.println("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
                                                "(cabinet.keypassword=student.keypassword OR \n" +
                                                "cabinet.rfid=student.keypassword OR cabinet.fingerprint=student.fingerprint) AND student.fingerprint" + "'" + msg + "'");
                                        if (queryResultSetJudgeTable.next()) {
                                            String x = queryResultSetJudgeTable.getString("cabinet_id");
                                            statement.execute("UPDATE cabinet SET fingerprint=" + "'" +  msg + "'" + " WHERE cabinet_id=" + "'" +
                                                    x + "'");
                                            System.out.println("UPDATE cabinet SET fingerprint=" + "'" +  msg + "'" + " WHERE cabinet_id=" + "'" +
                                                    queryResultSetJudgeTable.getString("cabinet_id") + "'");
                                        } else {
                                            Random rand = new Random();
                                            int x = 0;
                                            while (true) {
                                                x = rand.nextInt(1) + 1;
    //                                        System.out.println("x=" + x);
                                                if (!list.contains(x) && x != 0) {  // 2  3
    //                                            out.write(x);
    //                                            System.out.println("x=" + x);
    //                                            treeSetCabinet.add(x);
                                                    list.add(x);
    //                                            System.out.println(treeSetCabinet+"treeSetCabi");
                                                    break;
                                                }
                                            }
                                            statement.execute("INSERT INTO cabinet(cabinet_id, fingerprint) VALUES " + "('" + x + "','" + msg + "')");
                                            out.write(((Integer)x).toString().getBytes());
                                            System.out.println(((Integer)x).toString().getBytes());
                                        }
                                    }
                            }
    
    
                        } catch (Exception e) {
    //                        System.out.println(treeSetCabinet);
    //                        System.out.println(e);
                            e.printStackTrace();
                        }
                
                }
    

    首先声明一点arduino会发送三种数据到pc端,但是这三种数据都是数字的字符串,我是通过arduino板子收集的时候在前面增加标识符来对他们进行区别。
    Java代码的大概流程是这样的:


    Java

    再声明一下:在上面那个arduino代码中的Serial.print(str)就是发送的以&开头的数据

    发现错误

    在arduino端的操作是先按A,发送str,之后得到server端响应的数据也就是1,之后arduino再发送box1 LOW和box1 HIGH
    然后就是有一个很奇怪的现象就是第二次box1 LOW box1 HIGH 可以发送成功第一次就不能成功
    好吧出了问题那就疯狂调试呗,我的调试技巧就是打log

    先确定是不是Java这边出了问题

    一开始是我认为我代码的问题,然后我用这种方法做的测试:

    System.out.println(x.equals(1));
    

    然后事实证明不是Java这边的问题是
    不是Java这边那就是arduino那边喽!
    arduino这边由两部分组成一是它本身二是它的外接WiFi模块

    是不是arduino它本身出了问题

    不可能的第二次能成功就说明它从WiFi模块获取数据还是问题不大的

    那就应该是WiFi模块本身的问题了

    WiFi是用的TCP/IP协议来传输数据的那如何查看数据传输的情况呢?
    当然是一言不合就抓包了
    打开Wireshark
    这是出现问题的抓包情况

    抓包1
    微信截图_20180716142901.png
    这是正常的抓包情况
    ![微信截图_20180716143128.png](https://img.haomeiwen.com/i12687386/b00113c34f848 微信截图_20180716143202.png
    e92.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    微信截图_20180716143303.png
    从这几张截图中可以看出好像网络传输也没问题
    这怎末办?我好像束手无策啊?
    后来我又想了想网卡是插在主板上的,而那个外接的WiFi模块是通过IO来进行通信的,会不会是因为IO是有缓存的,这个是会消耗时间的

    解决问题成功

    我把代码这么改了下

    get_rfid();
          delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
         delay(10);
          get_correct_Box();
          open_box();
          break;
    

    果然不出问题了

    相关文章

      网友评论

        本文标题:Java socket编程一次奇怪的bug

        本文链接:https://www.haomeiwen.com/subject/tmeppftx.html