一.背景
既然是“遥控”炮台,那么就一定离不开远程交互控制,博主在这里选择的是我们都会有的手机作为客户控制端,Dragonboard410c作为服务器端响应手机的命令并控制我们的舵机进行转向。那么远程交互控制实现的问题点就转化成了android手机与linux服务器端的交互!看过博主以前文章的人,应该都看过博主曾经通过alljoyn技术和django服务器两种方式实现过远程交互的方式。今天,博主给大家分享第三种更简洁的交互方式,也就是我们搞系统的人都熟悉的socket通信!
二.android客户端程序
核心TcpClientConnector.java代码
package com.example.test;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TcpClientConnector {
private static TcpClientConnector mTcpClientConnector;
private Socket mClient;
private ConnectListener mListener;
private Thread mConnectThread;
public interface ConnectListener {
void onReceiveData(String data);
}
public void setOnConnectListener(ConnectListener listener) {
this.mListener = listener;
}
public static TcpClientConnector getInstance() {
if (mTcpClientConnector == null)
mTcpClientConnector = new TcpClientConnector();
return mTcpClientConnector;
}
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 100:
if (mListener != null) {
mListener.onReceiveData(msg.getData().getString("data"));
}
break;
}
}
};
public void createConnect(final String mSerIP, final int mSerPort) {
if (mConnectThread == null) {
mConnectThread = new Thread(new Runnable() {
@Override
public void run() {
try {
connect(mSerIP, mSerPort);
} catch (IOException e) {
e.printStackTrace();
}
}
});
mConnectThread.start();
}
}
/**
* 与服务端进行连接
*
* @throws IOException
*/
private void connect(String mSerIP, int mSerPort) throws IOException {
if (mClient == null) {
mClient = new Socket(mSerIP, mSerPort);
}
InputStream inputStream = mClient.getInputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
String data = new String(buffer, 0, len);
Message message = new Message();
message.what = 100;
Bundle bundle = new Bundle();
bundle.putString("data", data);
message.setData(bundle);
mHandler.sendMessage(message);
}
}
/**
* 发送数据
*
* @param data 需要发送的内容
*/
public void send(String data) throws IOException {
OutputStream outputStream = mClient.getOutputStream();
outputStream.write(data.getBytes());
}
/**
* 断开连接
*
* @throws IOException
*/
public void disconnect() throws IOException {
if (mClient != null) {
mClient.close();
mClient = null;
}
}
}
三.linux服务器程序
核心
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 8888 //服务器端监听端口号
#define MAX_BUFFER 1024 //数据缓冲区最大值
int main()
{
struct sockaddr_in server_addr, client_addr;
int server_sockfd, client_sockfd;
int size, write_size;
char buffer[MAX_BUFFER];
if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) //创建Socket
{
perror("Socket Created Failed!n");
exit(1);
}
printf("Socket Create Success!n");
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
bzero(&(server_addr.sin_zero), 8);
int opt = 1;
int res = setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //设置地址复用
if (res < 0)
{
perror("Server reuse address failed!n");
exit(1);
}
if (bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) //绑定本地地址
{
perror("Socket Bind Failed!n");
exit(1);
}
printf("Socket Bind Success!n");
if (listen(server_sockfd, 5) == -1) //监听
{
perror("Listened Failed!n");
exit(1);
}
printf("Listening ....n");
socklen_t len = sizeof(client_addr);
printf("waiting connection...n");
if ((client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &len)) == -1) //等待客户端连接
{
perror("Accepted Failed!n");
exit(1);
}
printf("connection established!n");
printf("waiting message...n");
while (1)
{
memset(buffer, 0, sizeof(buffer)); //清空数据缓冲区
if ((size = read(client_sockfd, buffer, MAX_BUFFER)) == -1) //读取客户端的数据
{
perror("Recv Failed!n");
exit(1);
}
if (size != 0)
{
buffer[size] = ' |