树莓派与安卓手机app的WIFI通信(局域网通信)

Posted 行稳方能走远

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树莓派与安卓手机app的WIFI通信(局域网通信)相关的知识,希望对你有一定的参考价值。

参照:树莓派与安卓手机app的WIFI通信(局域网通信)
作者:图触靓
发布时间: 2020-07-29 10:18:12
网址:https://blog.csdn.net/bhbhhyg/article/details/107655967

与树莓派与wemos的无线通信类似,只不过这次我们将客户端变为安卓手机,树莓派作为服务器。

 


   
  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include<netinet/in.h>
  4. #include <arpa/inet.h>
  5. #include<stdio.h>
  6. #include<stdlib.h>
  7. #include <unistd.h>
  8. #include<string.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. int initsocket(){
  13. int s_fd=socket(AF_INET, SOCK_STREAM, 0);
  14. if (s_fd== -1)
  15. {
  16. perror( "socket");
  17. exit( -1);
  18. }
  19. struct sockaddr_in addr;
  20. memset(&addr, 0, sizeof(struct sockaddr_in));
  21. addr.sin_family=AF_INET;
  22. addr.sin_port=htons( 9001); //端口号
  23. inet_aton( "192.168.200.XXX",&addr.sin_addr); //IP地址
  24. // addr.sin_port=htons(atoi(argv[2]));
  25. // inet_aton(argv[1],&addr.sin_addr);
  26. int bid=bind(s_fd,(struct sockaddr *)&addr, sizeof(struct sockaddr_in));
  27. listen(s_fd, 10);
  28. int len= sizeof(struct sockaddr_in);
  29. return s_fd;
  30. }
  31. int main(){
  32. char readbuf[ 2]={ 0};
  33. int s_fd=initsocket(); //初始化服务器
  34. printf( "wait connect.....\\n");
  35. while( 1){
  36. int fd_a=accept(s_fd, NULL, NULL); //该函数用来接受连接,没有连接的时候也可以用来阻塞while(1)
  37. printf( "connect\\n");
  38. memset(readbuf, 0, 2); //初始化字符串
  39. int r=read(fd_a,readbuf, 2); //读指令
  40. if(r== -1)
  41. {
  42. perror( "read");
  43. }
  44. else
  45. {
  46. printf( " cmd is %c \\n",readbuf[ 0]); //打印安卓客户端发来的指令
  47. }

安卓端连接服务器的方法


   
  1. package com.example.smarthome;
  2. import java.io.OutputStream;
  3. import java.net.Socket;
  4. import android.os.Handler;
  5. public class NetUtils {
  6. public String message;
  7. public String reTurnMes;
  8. public Handler handler;
  9. public NetUtils(String message) {
  10. this.message = message;
  11. }
  12. public NetUtils(String message, Handler handler) {
  13. this.message = message;
  14. this.handler = handler;
  15. }
  16. public void sendMessage() {
  17. new Thread( new Runnable() {
  18. @Override
  19. public void run() {
  20. try {
  21. Socket client = new Socket( "192.168.XXX.XXX", 9001); //与服务器对应的IP地址与端口号
  22. OutputStream out = client.getOutputStream();
  23. out.write(message.getBytes()); //像服务器发送信息
  24. out.close(); //关闭输入流
  25. client.close(); //客户端的连接
  26. } catch (Exception e) {
  27. // TODO Auto-generated catch block
  28. e.printStackTrace();
  29. }
  30. }
  31. }).start();
  32. }
  33. }

安卓AndroidManifest中需要添加的权限:


   
  1. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  2. <uses-permission android:name="android.permission.INTERNET" />

 

安卓按键发送的写法:


   
  1. Button kd=(Button)findViewById(R.id.kd);
  2. kd.setOnClickListener( new OnClickListener() {
  3. @Override
  4. public void onClick(View arg0) {
  5. new NetUtils( "A").sendMessage();
  6. }
  7. });

最后,需要注意的是,安卓给服务器发送数据是按键一次,建立一个线程并连接一次莓派端服务器,发送完成再断开。所以我们需要将树莓派端的服务器阻塞设置为连接,而不是一次连接后,不断的循环读客户端的数据,否则当客户端发完数据后,断开连接,服务器还一直在循环的读上一个连接的数据,造成死循环。

所以服务器正确的设置应该为,接受一次连接,读一次,阻塞等待下一次的连接。

以上是关于树莓派与安卓手机app的WIFI通信(局域网通信)的主要内容,如果未能解决你的问题,请参考以下文章

android 手机和树莓派之间通过 WiFi 进行通信,无需外部调制解调器/路由器?

树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库全双工通信

树莓派与Arduino Leonardo R3使用NRF24L01无线模块通信

树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 树莓派单子节点查询

树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库发送自定义数据

树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 树莓派查询子节点温湿度数据