便携式ROV搭建系列(二):通信之APP与树莓派的Socket通信

便携式ROV搭建系列(二):通信之APP与树莓派的Socket通信


1 Socket通信

原理及Java实现方式参考《Java Socket应用—通信是这样练成的》
socket通信模型
这里写图片描述
服务器端
这里写图片描述
客户端
这里写图片描述

2 Eclipse Java 实现

服务器端

package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * 基于TCP协议的Socket通信,实现用户登录
 * 服务器端
 */
public class Serve {
    public static void main(String[] args) {

        try {
            // 1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
            ServerSocket serverSocket=new ServerSocket(8888);

            // 2.调用accept()方法开始监听,等待客户端的连接
            System.out.println("***服务器即将启动,等待客户端的连接");
            Socket socket = serverSocket.accept();

            // 3.获取输入流,读取客户端信息
            InputStream is = socket.getInputStream();  // 字节输入流
            InputStreamReader isr = new InputStreamReader(is);  // 将字节流转换为字符流
            BufferedReader br = new BufferedReader(isr);  // 为输入流添加缓冲
            String info = null;
            while((info = br.readLine())!= null)  // 循环读取客户端信息,每次读一行,不为空便一直读
            {
                System.out.println("我是服务器,客户端说" + info);
            }
            socket.shutdownInput(); // 关闭输入流

            // 4.获取输出流,响应客户端的请求
            OutputStream os = socket.getOutputStream();
            PrintWriter pw = new PrintWriter(os); // 包装为打印流
            pw.write("x:111,222,你好"); //你好,我是服务器,欢迎你!
            pw.flush();  // 调用flush()方法将缓存输出

            // 5.关闭资源
            pw.close();
            os.close();
            br.close();  // 关闭BufferedReader
            isr.close();  // 关闭InputStreamReader
            is.close();  // 关闭InputStream
            socket.close();  
            serverSocket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

客户端

package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/*
 *  客户端
 */
public class Client {
    public static void main(String[] args) {

        try {
            // 1.创建客户端Socket,指定服务端地址和端口
            Socket socket = new Socket("localhost",8888);

            // 2.获取输出流,向服务器端发送信息
            OutputStream os = socket.getOutputStream();  // 字节输出流
            PrintWriter pw = new PrintWriter(os);  
            pw.write("用户名:admin;密码:123");
            pw.flush();
            socket.shutdownOutput(); 

            // 3.获取输入流,读取服务器端的响应信息
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String info = null;
            while((info = br.readLine())!= null)  // 循环读取客户端信息,每次读一行,不为空便一直读
            {
                System.out.println("我是客户端,服务端说:" + info);
            }

            // 4.关闭资源
            br.close();
            is.close();

            pw.close();
            os.close();
            socket.close();

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

3 ROV应用移植

APP端(Android Studio 实现):客户端

   //***************************** Socket通信 *****************************//
    // 创建Socket连接


    // 创建新线程
    public void sendConmmand(final String cmd)
    {
        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    acceptServer(cmd);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

    }


    // socket 通信步骤
    private void acceptServer(String command) throws IOException {
        //1.创建客户端Socket,指定服务器地址和端口
        socket = new Socket("192.168.31.221", 8888);  //192.168.31.221
        //2.获取输出流,向服务器端发送信息
        OutputStream os = socket.getOutputStream();//字节输出流
        PrintWriter pw = new PrintWriter(os);//将输出流包装为打印流
        // 获取客户端的IP地址
        InetAddress address = InetAddress.getLocalHost();
        String ip = address.getHostAddress();
        pw.write(command);
        pw.flush();
        socket.shutdownOutput();// 关闭输出流

        InputStream is = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(is,"UTF-8");  // ,"UTF-8"
        BufferedReader br = new BufferedReader(isr);

        response = br.readLine();
        // 通知主线程,将接受到的消息显示到界面
        Message msg = Message.obtain();
        msg.what = 0;
        mMainHandler.sendEmptyMessage(0);
        socket.shutdownInput();// 关闭输入流
        pw.close();
        os.close();
        br.close();   // 关闭BufferedReader
        isr.close();  // 关闭InputStreamReader
        is.close();   // 关闭InputStream
        socket.close();
    }

树莓派端(python 实现):服务端

import socket
import serial

try:
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
    print("create succ")
    ser = serial.Serial('/dev/ttyACM0',9600,timeout=1)  # arduino接口
    print("serial succ")
    sock.bind(('192.168.31.32',8888))  # ip地址和端口号
    print("bind succ")
    sock.listen(5)
    print("lisen succ")
except:
    print("init sock succ")
while True:
    print("listening for client")
    conn,addr = sock.accept()
    print("get client")
    print(addr)
    conn.settimeout(30)
    szBuf = conn.recv(1024)
    print("recv: " + str(szBuf,'utf-8'))
    ser.write(szBuf)
    respond = ser.readline();
    if "" = response
        conn.send(b"exit")
    else:
        conn.send(response) 
    print("ser.write")
    conn.close()    
    print("end")

猜你喜欢

转载自blog.csdn.net/la_fe_/article/details/81507707