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);
            }

}

N>是的,也许你会问,你需要jar,那就去下载吧!https://download.csdn.net/download/lixinkailixinkai/10623020

还有人脸识别:下回再说。

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 客户端代码:import websocket ws = websocket.WebSocket() ws.connect("ws://example.com/websocket")服务器代码:import websocket def on_message(ws, message): print(message)def on_error(ws, error): print(error)def on_close(ws): print("### closed ###")def on_open(ws): ws.send("Hello World")if __name__ == "__main__": websocket.enableTrace(True) ws = websocket.WebSocketApp("ws://example.com/websocket", on_message = on_message, on_error = on_error, on_close = on_close) ws.on_open = on_open ws.run_forever() ### 回答2: 以下是一个简单的示例,展示了如何在Python中使用websockets库实现客户端服务器之间的WebSocket连接,并实现互相推送的功能。 服务器端代码(server.py): ```python import asyncio import websockets # 存储所有已连接的客户端 connected_clients = set() # 处理客户端连接请求 async def handle_client(websocket, path): # 将新连接的客户端加入已连接的集合中 connected_clients.add(websocket) try: # 不断接收客户端发送的消息 async for message in websocket: print(f"Received message: {message}") # 将接收到的消息发送给所有其他已连接的客户端 await asyncio.wait([client.send(f"{websocket.remote_address[0]}: {message}") for client in connected_clients if client != websocket]) finally: # 客户端断开连接时将其移出已连接的集合 connected_clients.remove(websocket) # 启动WebSocket服务器 start_server = websockets.serve(handle_client, 'localhost', 8765) # 运行事件循环 asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever() ``` 客户端代码(client.py): ```python import asyncio import websockets # 处理接收到的消息 async def handle_message(message): print(f"Received message: {message}") # 向服务器发送消息 async def send_message(): async with websockets.connect('ws://localhost:8765') as websocket: while True: # 接收用户输入的消息 message = input("Enter a message to send: ") # 发送消息给服务器 await websocket.send(message) # 等待服务器返回的消息 response = await websocket.recv() # 处理接收到的消息 await handle_message(response) # 运行客户端 asyncio.get_event_loop().run_until_complete(send_message()) ``` 请注意,上述代码仅供示例和学习之用,并未考虑错误处理和安全性等问题。在实际应用中,需要根据具体情况进行适当的调整和优化。 ### 回答3: 客户端服务器建立WebSocket连接后,可以通过相应的库来实现互相推送消息。以下是一个使用Python的例子: 服务器端代码: ```python import asyncio import websockets # 定义处理WebSocket连接的函数 async def handle_websocket(websocket, path): while True: # 接收客户端发送的消息 client_message = await websocket.recv() print(f"收到客户端消息: {client_message}") # 向客户端发送消息 server_message = "服务器收到了你的消息" await websocket.send(server_message) # 创建WebSocket服务器 start_server = websockets.serve(handle_websocket, "localhost", 8888) # 异步运行服务器 asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever() ``` 客户端代码: ```python import asyncio import websockets # 定义处理WebSocket连接的函数 async def handle_websocket(): async with websockets.connect("ws://localhost:8888") as websocket: while True: # 向服务器发送消息 client_message = input("请输入要发送的消息:") await websocket.send(client_message) # 接收服务器发送的消息 server_message = await websocket.recv() print(f"收到服务器消息: {server_message}") # 异步运行客户端 asyncio.get_event_loop().run_until_complete(handle_websocket()) ``` 以上代码演示了如何使用Python中的`websockets`库实现基本的WebSocket连接和消息推送。在服务器端代码中,我们定义了一个处理WebSocket连接的函数`handle_websocket()`,通过注册此函数到WebSocket服务器中,来处理与客户端的通信。客户端代码中,我们同样定义了一个处理WebSocket连接的函数`handle_websocket()`,通过调用`websockets.connect()`函数来与服务器建立连接,然后可以通过`websocket.send()`和`websocket.recv()`方法来向服务器发送消息和接收消息。 需要注意的是,在实际使用中,可能需要在服务器客户端代码中进行一些逻辑的处理,以适应具体的业务需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值