便携式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")