1. 程式人生 > >STM32F4+WIFI模組TCP連結伺服器,伺服器與安卓客戶端Websocket長連結;實現監控資訊實時推送。

STM32F4+WIFI模組TCP連結伺服器,伺服器與安卓客戶端Websocket長連結;實現監控資訊實時推送。

  哈哈哈哈哈!這是筆者第一次寫這種東西,專案是我們大二的一個大創組的專案:(雖然很沒創新,導師也一棒子打死了)但是我們還是硬著頭皮完成了。

1>硬體端:stm32f429,紅外線感應,esp8266模組,ov5640攝像頭,步進電機,等等。

   主要是採集移動物體的影象jpg,通過無線傳輸模組傳遞給伺服器。這裡將硬體當作tcp客戶端。

2>伺服器端:java寫的,Java建立tcp伺服器程式碼如下:

public static void main(String[] args) throws IOException{
        ServerSocket ss=new ServerSocket(5670);//tcp伺服器
        socketserve socketServer = new socketserve(2017);//websocket伺服器
        socketServer.start();
        while(true) {
        Socket s=ss.accept();
        socketT t=new socketT(s,i,socketServer );
        new Thread(t).start();
        i++;
        }
  }
}
///////////////////////////////////////////////////////////////////////////////////////////  硬體的tcp伺服器
class socketT implements Runnable{
      private Socket client;
      private int i;//照片個數
  private socketserve android;
      InputStream in=null;
      public socketT(Socket client,int i,socketserve android ) {
        this.client=client;
        this.i=i;
        this.android=android;
       }
    @Override
    public void run() {
        int j,c=0;
        int d=0;
        try {
            in=client.getInputStream();
            byte []data =new byte[300000];
            byte []data1 = null;
            for(j=0;d!=0xFF||c!=0xD9;) {
               d=c;
               c=in.read();
               if(c!=-1) {
               data[j]=(byte)c;
               j++;
               }
            }
               data[j]=-2;
               data1=new byte[j+1];
               for(;j>=0;j--)
                   data1[j]=data[j];        
            //傳送給app
           android.sendToclient(data1);//websocket 伺服器主動推送給手機
            //存入電腦
            FileOutputStream op=new FileOutputStream(new File("D:/p/"+Integer.toString(i)+".jpg"));
              op.write(data1);
              op.close();
              ///////人臉識別呼叫
         /*    new Thread(new Runnable() {
                  byte[] data2=null;
                     @Override
                     public void run() {
                         picture.FeatureOrbLannbased("D:/p/"+Integer.toString(i)+".jpg","D:/p3/"+Integer.toString(i)+".jpg");
                         FileInputStream oo;
                         try {
                             oo = new FileInputStream(new File("D:/p3/"+Integer.toString(i)+".jpg"));
                             data2=new byte[oo.available()];
                                oo.read(data2);
                                android.sendToclient(data2);
                         } catch (Exception e) {
                             e.printStackTrace();
                         }
                         }
                 }).start();*/
            
        } catch (IOException e) {
            
            e.printStackTrace();
        }finally {
            try {
                in.close();
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            
        }
        
        
    }

這裡,我們不知道一張照片的大小是多大,所以只能用其結束符進行捕捉:jpg圖片的檔案是十六進位制數,每張jpg圖片以0xFF 0xD8開始,以0xFF 0xD9結束;所以我們從client 得到的inputsteam中讀取位元組,讀到結束符的時候就代表一張圖片的資料已經全部接收,就可以轉化為想要的圖片了。 值得我們注意的是:有時候inputsteam中的位元組已經全部讀取完畢,但是還沒讀到結束符;原因是一般是這樣的:客戶端(無論是硬體,還是在電腦上模擬的)傳送大檔案時候是一段一段傳送的,比如我的硬體是每次傳送1024個位元組,那一張高質量圖片要將近1M,所以不能一次傳送,於是就必須等待指導有結束符才結束。

還有:這裡是tcp短連結,要想長連線只需將其中的讀取位元組部分寫入死迴圈即可,就是處理完一張照片,將byte[] data陣列重新初始化,繼續從in中讀取。in和client一旦關閉,tcp斷開。當然長連線已不是一直的,據說是2個小時會斷開,我們用的區域網,額額額,晚上建立連結,早上起來還沒斷。

3>伺服器端的websocket長連線;這是好東西,可以實現伺服器端的資訊向客戶端的推送,實現起來也很簡單。狠狠的踢開http(hahahahaha!);httpok也有封裝這類東西。

public class socketserve extends WebSocketServer{
    public socketserve(int port)throws UnknownHostException{
        super(new InetSocketAddress(port));
    }
    public socketserve(InetSocketAddress address) {
        super(address);
    }

    @Override
    public void onClose(WebSocket webSocket, int i, String s, boolean b) {
        System.out.println("duankai");
    }

    @Override
    public void onError(WebSocket webSocket, Exception e) {
         if (null != webSocket) {
                webSocket.close(0);
            }
            e.printStackTrace();
        
    }

    @Override
    public void onMessage(WebSocket webSocket, String s) {
    }

    @Override
    public void onOpen(WebSocket webSocket, ClientHandshake clienthandshake) {
          sendToclient("OPEN");
          System.out.println("有客戶已經連結上伺服器");
          }

    @Override
    public void onStart() {
        // TODO Auto-generated method stub
        
    }
    //////////////////////////////////////
    public void sendToclient (String message) {
        Collection<WebSocket> connections = connections();
        //將訊息傳送給每一個客戶端
        for (WebSocket client : connections) {//這裡需要判斷客戶端是否是硬體的主人,如果是就傳送資訊
            client.send(message);
        }
        
    }
     public void sendToclient(ByteBuffer b) {
            Collection<WebSocket> connections = connections();
            //將訊息傳送給每一個客戶端
            for (WebSocket client : connections) {
                client.send(b);
            }
        }
     public void sendToclient(byte[] message) {
            Collection<WebSocket> connections = connections();
            //將訊息傳送給每一個客戶端
            for (WebSocket client : connections) {
                client.send(message);
            }
        }
    ////////////////////////////////////////
    
}

很簡單,可能是我們使用的太低階,嗯!可以傳送String   byte[]   bytebuffer三種;主動推送給客戶端。

4>android客戶端;我主要說我們的通訊連結模組

我們將其寫道一個後臺執行中,當出發app的某個開關之後,後臺一直執行,直到將他殺死。

public class service extends Service {
    private websocket client;
    private static final String url = "ws://你的伺服器ip:你的伺服器埠/";
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
      @Override  
        public void onCreate() {  
        
        }  
      
        @Override  
        public void onDestroy() {
            client.close();
           
        }  
      
        @Override  
        public void onStart(Intent intent, int startid) {
            websocket_init();
    
        }  
                
/////////////////////////////////////////////////////////////

    private void websocket_init(){
             client = new websocket(URI.create(url)) {
                @Override
                public void onMessage(ByteBuffer message) {
                    byte[] dat=new byte[message.remaining()];
                    message.get(dat, 0, dat.length);//得到伺服器端推送資訊
                    FileOutputStream fout;
                    try {
                        fout = new FileOutputStream(new File(Environment.getExternalStorageDirectory()+"/dachuang/",Integer.toString(data.shu()+1)+".jpg"));//存入手機固定的記憶體資料夾
                        fout.write(dat);
                        fout.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    addnotification("接收到警報訊息,點選檢視");//新增訊息欄提醒
                }

                @Override
                public void onMessage(String message) {
                    if(message=="OPEN");//接收到伺服器的訊息,這個訊息是   ,自己看吧,對照伺服器端程式碼
                    addnotification("連結成功");
                }
                
            };
            client.connect();
    }
    
    /////////////////    ///////
private  void addnotification(String str) {
            NotificationManager manager=(NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
                    Notification notification=new Notification();
                    //設定顯示在手機最上邊的狀態列的圖示
                    notification.icon=R.drawable.family;
                    notification.tickerText="注意了,我被扔到狀態列了";
                    notification.defaults=Notification.DEFAULT_SOUND;
                    notification.defaults =Notification.DEFAULT_VIBRATE;
                    notification.audioStreamType=android.media.AudioManager.ADJUST_LOWER;
                    Intent intent=new Intent(this,option_3.class);
                    PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
                    //點選狀態列的圖標出現的提示資訊設定
                     notification.setLatestEventInfo(this,"警報資訊:",str,pendingIntent);
                    manager.notify(1,notification);
            }

}

還有人臉識別:下回再說,累死了!!

相關推薦

STM32F4+WIFI模組TCP連結伺服器伺服器客戶Websocket連結實現監控資訊實時

  哈哈哈哈哈!這是筆者第一次寫這種東西,專案是我們大二的一個大創組的專案:(雖然很沒創新,導師也一棒子打死了)但是我們還是硬著頭皮完成了。 1>硬體端:stm32f429,紅外線感應,esp8266模組,ov5640攝像頭,步進電機,等等。    主要是採集移動物

POI匯出時寫一份到ftp伺服器一份下載給客戶 ftp伺服器搭建(離線安裝vsftpd)配置 poi實現百萬級資料匯出 oi實現百萬級資料匯出

導語:   昨天接到專案經理這麼一個需求,讓我在POI匯出Excel的時候寫一份到我之前搭建的ftp伺服器上。所以就有了這篇部落格首先我們來分析下之前的業務邏輯:我們建立並構造了一個workbook,然後構建了一個OutputStream輸出流,然後我們把資料寫入輸出流中就可以被客戶端下載。   現在我們

Linux RedHat6.4 下安裝ORACLE資料庫伺服器win10下安裝ORACLE客戶 問題總結

前一段時間由於工作需要安裝了ORACLE 11g資料庫在Linux上,安裝過程中遇到了很多問題,所以在這裡總結一下,希望能幫到需要的人。 問題1:安裝過程中提示 pdksh 系統軟體缺失,用rpm -qi 命令查詢確實沒有安裝該軟體,但是安裝了另一個叫 ksh 的系統軟體,二者名字很相似

WebService 客戶呼叫和伺服器搭建

這段時間做了一個小程式,想通過WebService來供安卓客戶端呼叫。先說一下安卓端的程式。之前沒有進行過安卓+Java的程式設計,就先找網上的一個查詢手機號碼歸屬地例子來測試WebService。 在Android平臺呼叫Web Service需要依賴於第三

基於tigase伺服器客戶開發---註冊登入

 首先感謝簡書大牛richsjeson發表的部落格(地址http://www.jianshu.com/p/12e1055afca1)對我使用jaxmpp的啟蒙作用! 1 什麼是tigase?與之前的o

微信H5客戶app支付中遇到的問題處理: 商家引數格式有誤請聯絡商家解決

解決在APP中使用微信H5支付,提示“商家引數格式有誤…” 引子:近期碰到了微信支付的新需求,用到微信H5支付,後發現如果只使用瀏覽器做H5支付, 沒什麼問題,主流的手機瀏覽器均已測試,都可以調起微信支付(QQ,UC,百度 ) 但是當我在APP中喚起的時候,安卓總是出現“商家引數格式有誤,請

資料到客戶(php版)

由於專案開發需要,需要服務端推送資料到安卓客戶端,最終選擇了第三方的個推資料推送。準備工作個推官網有詳細介紹,此處不做詳解。基本推算原理:在個推註冊繫結客戶端後,每一個客戶端會有一個唯一的客戶端id,通過傳送推送內容到客戶端完成訊息推送。以下介紹個推兩個推送型別(單個推送):

Java服務模擬websocket客戶建立連結之---WebSocketClient

    最近專案裡需要在Java服務端與c++進行websocket通訊,java_websocket.client.WebSocketClient外掛很好的解決了這個需求。    首先需要在pom.xml檔案中引入此依賴: <dependency> &

【隨堂筆記】unity開發中Socket的用法(一實現伺服器客戶簡單的連結

實現了簡單的連結,也增加了客戶端沒有連結到伺服器的自動重連 伺服器程式碼 using System; using System.Net; using System.Net.Sockets; namespace SeverSocket { class Program

ESP8266 wifi模組正常上電處理過程

wifi模組正常上電,需要涉及ESP8266 NOS SDK的 wifi介面部分、TCP/UDP部分  還有使用者引數區訪問部分。 /********************user_init函式***********************************/ void

13-編寫WIFI模組連線MQTT程式和除錯助手測試通訊

  直接上程式吧 local SubscribeTopic = "wifi/user".."/"..clientid PublishTopic = "wifi/device".."/"..clientid local UsartReceiveData=""; lo

WebSocket 教程關於伺服器實時

原文出處: http://www.ruanyifeng.com/blog/2017/05/websocket.html WebSocket 是一種網路通訊協議,很多高階功能都需要它。 本文介紹 WebSocket 協議的使用方法。 一、為什麼需要 WebSocket?

【微信小程式控制硬體②】 開始微信小程式之旅匯入小程式Mqtt客戶原始碼實現簡單的驗證和通訊於伺服器!(附帶原始碼)

本博文由熱愛分享熱愛技術的半顆心臟原創,非官方人員、非組織名義編寫,博文如有不對或侵犯您的權益,請及時留言,第一時間糾正! 一、前言; 繼續我們的小程式控制智慧硬體(包括esp8266)學

使用xbmc/kodi作為dlna render裝置時連線到某些wifi熱點/路由器上不能被dlna control找到發現的問題——原因是WIFI模組深度優化後從省電模式喚醒時會丟失組播包

測試環境及條件如下: 1)wifi熱點為我們工作環境用的普通路由器時,xbmc安裝在開發板上,作為dlna render裝置時,是可以被dlna control(為手機上的音樂apk,如魅族MX4 Pro自帶的音樂apk)發現的。 但是,當wifi熱點是採用tplink的T

Linux----網路程式設計(TCP網路通訊伺服器客戶程式設計流程與其迴圈實現

一、TCP的伺服器客戶端程式設計流程 1、伺服器 ser.c 1 #include <stdio.h> 2 #include <assert.h> 3 #incl

rt3070 無線wifi模組移植到linux並連線無線路由上網

Linux發行版:ubuntu 10.4 無線網絡卡晶片:rt3070 路由器加密方式;WPA-PSK/AES 驅動:2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO.bz2 一 安裝驅動 (1) 驅動

同時上傳文字和圖片到伺服器伺服器接收並處理

(更簡單的方法,點選安卓端同時上傳圖片和文字,伺服器接收並處理(二)) 之前看了很多部落格,找到的無非就是要麼只上傳json,要麼只上傳圖片。碰了許多的壁,因此我這裡寫一下自己已經測試成功的程式碼。 Android端使用Post上傳圖片和json程式碼 注

linux採用scp命令拷貝檔案到本地拷貝本地檔案到遠端伺服器伺服器之間傳輸檔案

拷貝遠端伺服器的檔案到本地: scp -r -P  埠號   使用者名稱@IP地址:/usr/local/tomcat_airc/webapps/        /tmp/kyj/ 拷貝本地檔案到遠端伺服器: scp -r    /tmp/kyj/sys.war

android開發:如果處理同樣的應用程式在不同機器上執行正常但是後臺伺服器互動響應時間不一樣的問題?

情景問題 專案中用到一個安卓應用程式,在不同的機器上,執行正常,與後臺伺服器互動響應時間不一樣,當是安卓應用程式在接受到請求,處理一下耗時操作,比如操作s qlite3,沒有即時反饋資訊給

go伺服器mfc做客戶的簡單群聊Demo

//先前程式碼對中文處理有問題,以下程式碼做了修正, //go語言伺服器程式碼 package main import( "fmt" "net" "strconv" "runtime" //go執行緒庫 "strings" ) var conns map[string]ne