【转载】android客服端+eps8266+单片机+路由器之远程控制系统

用android客服端+eps8266+单片机+路由器做了一个远程控制的系统,因为自己是在实验室里,所以把实验室的门,灯做成了远程控制的。

控制距离有多远------只能说很远很远,只要你手机能上网的地方,不对应该是只要能打电话的地方,不对应该是只要是移动网(我用的是移动的卡)覆盖的地方,

这篇只说明怎么样才能实现远程通信(在路由器上怎样设置,wifi模块eps8266怎样设置),最后会贴上单片机,android的源码

请事先参考我的前几篇文章

android之WIFI小车编程详述

android 之TCP客户端编程

ESP8266使用详解

有人的设置方法介绍

http://www.usr.cn/Faq/146.html

http://www.usr.cn/Faq/148.html

另外

ESP8266使用详解中介绍过它的连接路由器的模式,让它连接上路由器后需要做一些设置

我做的手机tcp客服端

关于上面的远程 与 近程连接

远程连接:

当手机是2G,3G,4G上网的时候,或者,连接了wifi模块所连接的路由器的时候,或者所连接的路由器桥接了wifi模块所连接的路由器。

远程连接服务器ip是路由器的公网ip

对于通信端口号是设置wifi模块所监听的端口号(它通信的端口号)

unsigned char code CIPSERVER[]="AT+CIPSERVER=1,10000\r\n";//开启服务器模式,端口号10000

近程连接:

因为我设置了wifi模块AP 兼 Station 模式,所以模块会发出无线信号,我连接它的wifi信号也能完成通信,只不过连接它的wifi信号后,要连接的ip地址为192.168.4.1

好了附上单片机程序,本来我设置了返回数据,但是因为我的灯和门并没有加检测所以后来就去掉了

#define _MAIN_C_
#include "include.h"
sbit L1 = P1^0;
sbit L2 = P1^1;
sbit L3 = P1^2;
sbit L4 = P1^3;
sbit kaiguan = P1^4;
sbit led1 = P1^5;
sbit led2 = P1^6;
//AP
unsigned char code CWMODE2[]="AT+CWMODE=2\r\n";     //设置模块的工作的模式为AP模式

//多连接ap+station模式
unsigned char code CWMODE3[]="AT+CWMODE=3\r\n";     //设置模块的工作的模式为ap+station模式
unsigned char code CWJAP[]="AT+CWJAP=\"TP-LINK_9750\",\"56565888\"\r\n";//设置连接的路由器

unsigned char code RST[]="AT+RST\r\n";                     //重启模块使AT+CWMODE模式生效
unsigned char code CIPMUX[]="AT+CIPMUX=1\r\n";            //启动多连接
unsigned char code CIPSERVER[]="AT+CIPSERVER=1,10000\r\n";//开启服务器模式,端口号10000
//微秒延时
/*
void us_delay(unsigned char t)
{
    while(t--);
} */
//ms秒延时
void Delay_ms(unsigned long ms)
{
    unsigned char i, j,k;
    for(k=0;k<ms;k++)
    {
        _nop_();
        _nop_();
        i = 22;
        j = 128;
        do
        {
            while (--j);
        } while (--i);
    }
}
void delay1s(void)   //误差 -0.00000000024us
{
    unsigned char a,b,c;
    for(c=95;c>0;c--)
        for(b=26;b>0;b--)
            for(a=185;a>0;a--);
}
//ESP8266设置
void ESP8266_Set(unsigned char *puf)
{
    while(*puf!=‘\0‘)
    {
        Send_Uart(*puf);
        puf++;
    }
}

//多连接AP模式
void ManyConnect_AP()
{
    P1=0xff;
    //模式ap
    while(1)
    {
        ESP8266_Set(CWMODE2);//返回ok
        delay1s();
        if(Usart_AT_flage ==1)
        {
            if(strstr(Usart_Receive, "OK") )
            {
                Usart_AT_flage = 0;
                L1 = 0;
                break;
            }
        }
  }
    //复位
    ESP8266_Set(RST);//返回一大溜,不用判断返回
    delay1s();
    delay1s();
    //多连接
    while(1)
    {
        ESP8266_Set(CIPMUX);//返回ok
        delay1s();
        if(Usart_AT_flage ==1)
        {
            if(strstr(Usart_Receive, "OK") )
            {
                Usart_AT_flage = 0;
                L2 = 0;
                break;
            }
        }
  }
    //启动TCP服务
    while(1)
    {
        ESP8266_Set(CIPSERVER);//返回ok,多了也返回ok
        delay1s();
        if(Usart_AT_flage ==1)
        {
            if(strstr(Usart_Receive, "OK") )
            {
                Usart_AT_flage = 0;
                L3 = 0;
                break;
            }
        }
  }
}

//多连接AP+Station 模式
void ManyConnect_ap_Station()
{
    P1=0xff;
    //模式3
    while(1)
    {
        ESP8266_Set(CWMODE3);//返回ok
        delay1s();
        if(Usart_AT_flage ==1)//接收完成
        {
            if(strstr(Usart_Receive, "OK") )
            {
                Usart_AT_flage = 0;
                L1 = 0;
                break;
            }
        }
  }
    //连接路由
    while(1)
    {
        //复位
        ESP8266_Set(RST);//返回一大溜,不用判断返回
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        ESP8266_Set(CWJAP);//返回ok
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        delay1s();
        if(Usart_AT_flage ==1)
        {
            if(strstr(Usart_Receive, "OK") )
            {
                Usart_AT_flage = 0;
                L2 = 0;
                break;
            }
        }
  }
    //多连接
    while(1)
    {
        ESP8266_Set(CIPMUX);//返回ok
        delay1s();
        if(Usart_AT_flage ==1)
        {
            if(strstr(Usart_Receive, "OK") )
            {
                Usart_AT_flage = 0;
                L3 = 0;
                break;
            }
        }
  }
    //启动TCP服务
    while(1)
    {
        ESP8266_Set(CIPSERVER);//返回ok,多了也返回ok
        delay1s();
        if(Usart_AT_flage ==1)
        {
            if(strstr(Usart_Receive, "OK") )
            {
                Usart_AT_flage = 0;
                L4 = 0;
                break;
            }
        }
  }
}

void delay1s500ms(void)   //误差 -0.000000000341us
{
    unsigned char a,b,c;
    for(c=123;c>0;c--)
        for(b=212;b>0;b--)
            for(a=25;a>0;a--);
}

void main()
{
    int i;
    InitUART();
    while(1)
    {
        //ManyConnect_AP();//多连接AP模式
        ManyConnect_ap_Station();//多连接AP+station模式
        while(1)
        {
            //由于消息的开头是+IP  故做此判断,00000000000000000号
            if((Usart_Receive[0]==‘+‘)&&(Usart_Receive[1]==‘I‘)&&(Usart_Receive[2]==‘P‘))
            {
                if((Usart_Receive[3]==‘D‘)&&(Usart_Receive[5]==‘0‘)&&(Usart_Receive[6]==‘,‘))
                {
                    if(Usart_Receive[9]==‘1‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                        delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }

                        //ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        //delay1s();
                        //ESP8266_Set("1");//向服务器发送数据

                        //delay1s();
                        //ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        //delay1s();
                        //ESP8266_Set("1");//向服务器发送数据
                    }
                    if(Usart_Receive[9]==‘2‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                        delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }
                        //ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        //delay1s();
                        //ESP8266_Set("2");//向服务器发送数据

                        //delay1s();
                        //ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        //delay1s();
                        //ESP8266_Set("2");//向服务器发送数据
                    }
                    if(Usart_Receive[9]==‘3‘)
                    {
                        led1 = 0;
                        delay1s();
                        delay1s();
                        //ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        //delay1s();
                        //ESP8266_Set("3");//向服务器发送数据

                        //ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        //delay1s();
                        //ESP8266_Set("3");//向服务器发送数据
                    }
                    if(Usart_Receive[9]==‘4‘)
                    {
                        led1 = 1;
                        delay1s();
                        delay1s();
                        /*
                        ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        delay1s();
                        ESP8266_Set("4");//向服务器发送数据

                        ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        delay1s();
                        ESP8266_Set("4");//向服务器发送数据*/
                    }
                    if(Usart_Receive[9]==‘5‘)
                    {
                        led2 = 0;
                        delay1s();
                        delay1s();
                        /*
                        ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        delay1s();
                        ESP8266_Set("5");//向服务器发送数据

                        ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        delay1s();
                        ESP8266_Set("5");//向服务器发送数据/*/
                    }
                    if(Usart_Receive[9]==‘6‘)
                    {
                        led2 = 1;
                        delay1s();
                        delay1s();
                        /*
                        ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        delay1s();
                        ESP8266_Set("6");//向服务器发送数据

                        ESP8266_Set("AT+CIPSEND=0,1\r\n");
                        delay1s();
                        ESP8266_Set("6");//向服务器发送数据*/
                    }
                }
            }
                //由于消息的开头是+IP  故做此判断,111111111111111111111号
            if((Usart_Receive[0]==‘+‘)&&(Usart_Receive[1]==‘I‘)&&(Usart_Receive[2]==‘P‘))
            {
                if((Usart_Receive[3]==‘D‘)&&(Usart_Receive[5]==‘1‘)&&(Usart_Receive[6]==‘,‘))
                {
                    if(Usart_Receive[9]==‘1‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                        delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }
                    }
                    if(Usart_Receive[9]==‘2‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                        delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }

                    }
                    if(Usart_Receive[9]==‘3‘)
                    {
                        led1 = 0;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘4‘)
                    {
                        led1 = 1;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘5‘)
                    {
                        led2 = 0;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘6‘)
                    {
                        led2 = 1;

                        delay1s();delay1s();
                    }
                }
            }
                //由于消息的开头是+IP  故做此判断,222222222222222号
            if((Usart_Receive[0]==‘+‘)&&(Usart_Receive[1]==‘I‘)&&(Usart_Receive[2]==‘P‘))
            {
                if((Usart_Receive[3]==‘D‘)&&(Usart_Receive[5]==‘2‘)&&(Usart_Receive[6]==‘,‘))
                {
                    if(Usart_Receive[9]==‘1‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                        delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }
                    }
                    if(Usart_Receive[9]==‘2‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                        delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }
                    }
                    if(Usart_Receive[9]==‘3‘)
                    {
                        led1 = 0;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘4‘)
                    {
                        led1 = 1;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘5‘)
                    {
                        led2 = 0;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘6‘)
                    {
                        led2 = 1;

                        delay1s();delay1s();
                    }
                }
            }
                //由于消息的开头是+IP  故做此判断,00000000000000000号
            if((Usart_Receive[0]==‘+‘)&&(Usart_Receive[1]==‘I‘)&&(Usart_Receive[2]==‘P‘))
            {
                if((Usart_Receive[3]==‘D‘)&&(Usart_Receive[5]==‘3‘)&&(Usart_Receive[6]==‘,‘))
                {
                    if(Usart_Receive[9]==‘1‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                    delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }
                    }
                    if(Usart_Receive[9]==‘2‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                        delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }
                    }
                    if(Usart_Receive[9]==‘3‘)
                    {
                        led1 = 0;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘4‘)
                    {
                        led1 = 1;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘5‘)
                    {
                        led2 = 0;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘6‘)
                    {
                        led2 = 1;

                        delay1s();delay1s();
                    }
                }
            }
                //由于消息的开头是+IP  故做此判断,444444444444444444号
            if((Usart_Receive[0]==‘+‘)&&(Usart_Receive[1]==‘I‘)&&(Usart_Receive[2]==‘P‘))
            {
                if((Usart_Receive[3]==‘D‘)&&(Usart_Receive[5]==‘0‘)&&(Usart_Receive[6]==‘,‘))
                {
                    if(Usart_Receive[9]==‘1‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                        delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }
                    }
                    if(Usart_Receive[9]==‘2‘)
                    {
                        kaiguan = 0;
                        delay1s500ms();
                        kaiguan = 1;
                        delay1s();
                        for(i = 0 ; i<20; i++)
                        {
                            Usart_Receive[i]=‘ ‘;
                        }
                    }
                    if(Usart_Receive[9]==‘3‘)
                    {
                        led1 = 0;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘4‘)
                    {
                        led1 = 1;

                    delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘5‘)
                    {
                        led2 = 0;

                        delay1s();delay1s();
                    }
                    if(Usart_Receive[9]==‘6‘)
                    {
                        led2 = 1;

                        delay1s();delay1s();
                    }
                }
            }

        }
    }
}

#define _USART_C_
#include "include.h"
unsigned char Usart_Receive[20]={0};
unsigned char Usart_Cnt=0;
bit Usart_AT_flage;
bit flage;
bit Command_Flag;

void InitUART(void)
{
    TMOD = 0x20;
    SCON = 0x50;
    TH1 = 0xFD;
    TL1 = TH1;
    PCON = 0x00;
    EA = 1;
    ES = 1;
    TR1 = 1;
}

void Send_Uart(unsigned char value)
{
    ES=0;  //关闭串口中断
    TI=0;   //清发送完毕中断请求标志位
    SBUF=value; //发送
    while(TI==0); //等待发送完毕
    TI=0;   //清发送完毕中断请求标志位
    ES=1;  //允许串口中断
}

void UARTInterrupt(void) interrupt 4
{
    if(RI)
    {
        RI=0;
        Usart_Receive[Usart_Cnt]=SBUF;//接收串口数据
        Usart_Cnt++;//
        //返回数据以回车结尾,有回车,而且数据个数大于2,说明接收到了数据
        if(Usart_Receive[Usart_Cnt-2]==‘\r‘ && Usart_Receive[Usart_Cnt-1]==‘\n‘ && Usart_Cnt >= 2)
        {
            Usart_Cnt = 0;//接收数据计数清零
            Usart_AT_flage = 1;//数据接收成功标志位
        }
        else if(Usart_Cnt > 20)//
        {
            Usart_Cnt = 0;
        }
    }
}

#ifndef __USART_H_
#define __USART_H_

#ifndef _USART_C_
#define _USART_ex_ extern
#else
#define _USART_ex_
#endif

_USART_ex_ unsigned char Usart_Receive[20];
_USART_ex_ unsigned char Usart_Cnt;
_USART_ex_ bit Usart_AT_flage;
_USART_ex_ bit Command_Flag;
_USART_ex_ unsigned char UsartData;
_USART_ex_ void InitUART(void);//串口初始化
_USART_ex_ void Send_Uart(unsigned char value);
#endif

#include <REGX52.H>
#include "USART.h"
#include <string.h>
#include <intrins.h>

完了,,,,,,,

android代码

package com.laboratory_control.yang;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

import android.R.integer;
import android.R.string;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    String imei;//手机imei号
    long long_mima;
    String string_mima;
    private SharedPreferences pref;
    private SharedPreferences.Editor editor;
    private CheckBox rememberpass;
    static Socket socket = null;//定义socket
    Button shenqing_button;//申请密钥
    Button LandingButton;//登陆按钮
    Button FarButton;//远程连接按钮
    Button NearButton;//进程连接按钮
    EditText PasswordEditText;//密码输入框
    EditText FarIpEditText;//远程ip输入框
    EditText NearIpEditText;//近程ip输入框
    EditText PortText;//定义端口输入框
    static InputStream inputStream=null;//定义输入流
    static OutputStream outputStream=null;//定义输出流
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pref = PreferenceManager.getDefaultSharedPreferences(this);
        rememberpass = (CheckBox) findViewById(R.id.cb_mima);

        shenqing_button = (Button) findViewById(R.id.shenqingButton);//申请密钥
        LandingButton = (Button) findViewById(R.id.dengluButton);//登陆
        FarButton = (Button) findViewById(R.id.yuanButton);//远程按钮
        NearButton = (Button) findViewById(R.id.jinButton);//进程按钮

        FarIpEditText = (EditText) findViewById(R.id.IPEditText);//远程ip输入框
        NearIpEditText = (EditText) findViewById(R.id.jinIPEditText);//进程ip输入框
        PortText = (EditText) findViewById(R.id.PORTEditText);//通信端口
        PasswordEditText = (EditText) findViewById(R.id.mimaEditText);//登陆密码

        boolean isRemember = pref.getBoolean("cb_mima", false);//得到cb_mima文件存的值,得不到会返回false
        if (isRemember) //如果上次选择了保存密码
        {
            //Toast.makeText(MainActivity.this, "123", Toast.LENGTH_SHORT).show();
            String password = pref.getString("password", "");//取出密码
            PasswordEditText.setText(password);//把密码输入到密码输入框
            rememberpass.setChecked(true);//选中记住密码
        }

        shenqing_button.setOnClickListener(shenqing_buttonListener);
        FarButton.setOnClickListener(FarButtonListener);//远程监听
        NearButton.setOnClickListener(NearButtonListener);//进程监听
        LandingButton.setOnClickListener(LandingButtonListener);//登陆监听

        /**
         * 获取IMEI号,IESI号,手机型号
         */
        getInfo();

        /**
         * 为完全退出应用程序而加的代码
         */
        ExitApplication.getInstance().addActivity(this);
    }
    /**
     * 申请密钥监听
     */
    private OnClickListener shenqing_buttonListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Toast.makeText(MainActivity.this,"请把"+imei+"提供给管理员",Toast.LENGTH_LONG).show();
        }
    };
    /**
     * 远程按钮连接监听
     */
    private OnClickListener FarButtonListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            //启动远程连接线程
            FarConnect_Thread farconnect_Thread = new FarConnect_Thread();
            farconnect_Thread.start();
        }
    };
    /**
     * //近程按钮连接监听
     */
    private OnClickListener NearButtonListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            NearConnect_Thread nearconnect_Thread = new NearConnect_Thread();
            nearconnect_Thread.start();
        }
    };
    /**
     *
     * 近程连接线程
     *
     */
    class NearConnect_Thread extends Thread//继承Thread
    {
        public void run()//重写run方法
        {
            try
            {
                if(true)
                //if (socket == null)
                {
                    //用InetAddress方法获取ip地址
                    InetAddress ipAddress = InetAddress.getByName(NearIpEditText.getText().toString());
                    int port =Integer.valueOf(PortText.getText().toString());//获取端口号
                    socket = new Socket(ipAddress, port);//创建连接地址和端口
                    if (socket !=null)
                    {
                        runOnUiThread(new Runnable()
                        {
                            public void run()
                            {
                                // TODO Auto-generated method stub
                                Toast.makeText(MainActivity.this,"已成功连接!", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                }
                /*
                else
                {
                    runOnUiThread(new Runnable()
                    {
                        public void run()
                        {
                            // TODO Auto-generated method stub
                            Toast.makeText(MainActivity.this,"成功连接!输入密码后即可登陆", Toast.LENGTH_SHORT).show();
                        }
                    });
                }*/
            }
            catch (Exception e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    /**
     *
     * 远程连接线程
     *
     */

    class FarConnect_Thread extends Thread//继承Thread
    {
        public void run()//重写run方法
        {
            try
            {
                if(true)
                //if (socket == null)
                {
                    //用InetAddress方法获取ip地址
                    InetAddress ipAddress = InetAddress.getByName(FarIpEditText.getText().toString());
                    int port =Integer.valueOf(PortText.getText().toString());//获取端口号
                    socket = new Socket(ipAddress, port);//创建连接地址和端口
                    if (socket !=null)
                    {
                        runOnUiThread(new Runnable()
                        {
                            public void run()
                            {
                                // TODO Auto-generated method stub
                                Toast.makeText(MainActivity.this,"成功连接!输入密码后即可登陆", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                }
                /*
                else
                {
                    runOnUiThread(new Runnable()
                    {
                        public void run()
                        {
                            // TODO Auto-generated method stub
                            Toast.makeText(MainActivity.this,"已经连接!", Toast.LENGTH_SHORT).show();
                        }
                    });
                }*/
            }
            catch (Exception e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    /**
     * 登陆监听,启动控制Activity(活动)
     */
    private OnClickListener LandingButtonListener =  new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            //if(true)
            String password = PasswordEditText.getText().toString();//得到输入框输入的密码

            if (socket !=null)//连接成功
            {
                if (PasswordEditText.getText().toString().equals(string_mima))//密码正确
                {
                     editor = pref.edit();
                     if (rememberpass.isChecked())
                     {
                        editor.putBoolean("cb_mima", true);
                        editor.putString("password", password);
                     }
                     else
                     {
                         editor.clear();
                     }
                     editor.commit();
                     Intent intent = new Intent();
                     intent.setClass(MainActivity.this, Control.class);
                     MainActivity.this.startActivity(intent);
                }
                else
                {
                    runOnUiThread(new Runnable()
                    {
                        public void run()
                        {
                            // TODO Auto-generated method stub
                            Toast.makeText(MainActivity.this,"已连接,请输入正确密码!", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
            else
            {
                runOnUiThread(new Runnable()
                {
                    public void run()
                    {
                        // TODO Auto-generated method stub
                        Toast.makeText(MainActivity.this,"请先连接!", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        }
    };
    /**
     * 退出提示框
     */
    protected void dialog() {
         AlertDialog.Builder builder = new Builder(MainActivity.this);
         builder.setMessage("亲,确定要退出吗");
         builder.setTitle("提示");
         builder.setPositiveButton("确定",
          new android.content.DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
           dialog.dismiss();
           MainActivity.this.finish();
           }
          });
         builder.setNegativeButton("取消",
          new android.content.DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
           dialog.dismiss(); 

           }
          });
         builder.create().show();
        }
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
          dialog();
          return false;
         }
         return false;
        }
        /**
         * 获取IMEI号,IESI号,手机型号
         */
        private void getInfo() {
               TelephonyManager mTm = (TelephonyManager)this.getSystemService(TELEPHONY_SERVICE);
               imei = mTm.getDeviceId(); 

               String aaaa = imei.substring(0,6);

               long_mima = Integer.parseInt(aaaa);
               long_mima = long_mima/3+666;//做运算当作登陆密码
               string_mima = ""+long_mima;

               //String imsi = mTm.getSubscriberId();
               //String mtype = android.os.Build.MODEL; // 手机型号
               //String mtyb= android.os.Build.BRAND;//手机品牌
               //String numer = mTm.getLine1Number(); // 手机号码,有的可得,有的不可得  

               Log.i("text", "手机IMEI号:"+imei);
               Log.i("456", string_mima);
           }
}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:background="@drawable/dd2"
    tools:context="com.laboratory_control.yang.MainActivity" >

    <!-- IP地址 -->
    <TextView
        android:text="远程连接服务器IP:"
        android:id="@+id/IPTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textSize="20dp"

        />
    <!-- 远程IP地址输入框 -->
    <EditText
        android:text=""
        android:id="@+id/IPEditText"
        android:layout_height="35dp"
        android:layout_width="match_parent"
        android:layout_marginTop="25dp"
        android:background="@android:color/white"
        />
     <!-- 近程IP地址 -->
    <TextView
        android:text="近程连接服务器IP:"
        android:id="@+id/jinTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textSize="20dp"
        android:layout_marginTop="70dp"
        />
    <!-- 近程IP地址输入框 -->
    <EditText
        android:text="192.168.4.1"
        android:id="@+id/jinIPEditText"
        android:layout_height="35dp"
        android:layout_width="match_parent"
        android:layout_marginTop="95dp"
        android:background="@android:color/white"
        />

    <!-- 端口号 -->
    <TextView
        android:text="通信端口号:"
        android:id="@+id/PORTTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textSize="20dp"
        android:layout_marginTop="140dp"
        />
    <!-- 端口号输入框 -->
    <EditText
        android:text="10000"
        android:id="@+id/PORTEditText"
        android:layout_height="35dp"
        android:layout_width="fill_parent"
        android:layout_marginTop="165dp"
        android:background="@android:color/white"
        />
   <!-- 密码 -->
    <TextView
        android:text="登陆密码:"
        android:id="@+id/mimaTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_marginTop="210dp"
        android:textSize="20dp"
        />
    <!-- 密码输入框 -->
    <EditText 

        android:id="@+id/mimaEditText"
        android:layout_height="35dp"
        android:layout_width="fill_parent"
        android:layout_marginTop="235dp"
        android:hint="请输入登陆密码"
        android:inputType="textPassword"
        android:background="@android:color/white"
        />
    <!-- 记住密码复选框 -->
    <CheckBox
            android:id="@+id/cb_mima"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/mimaEditText"
            android:textSize="20dp"
            android:text="记住密码"
            />
     <!-- 近程按钮 -->
    <Button
        android:id="@+id/jinButton"
        android:layout_height="70dp"
        android:layout_width="100dp"
        android:text="近程连接"
        android:layout_alignParentRight="true"
        android:layout_marginTop="380dp"
        />
    <!-- 登陆按钮 -->
    <Button
        android:id="@+id/dengluButton"
        android:layout_height="70dp"
        android:layout_width="100dp"
        android:text="登陆"
        android:layout_marginTop="380dp"
        android:layout_centerHorizontal="true"
        />
    <!-- 远程连接按钮 -->
    <Button
        android:id="@+id/yuanButton"
        android:layout_height="70dp"
        android:layout_width="100dp"
        android:text="远程连接"
        android:layout_alignParentLeft="true"
        android:layout_marginTop="380dp"
        />
    <!-- 申请密钥 -->
    <Button
        android:id="@+id/shenqingButton"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="申请密钥"
        android:layout_alignParentRight="true"
        android:layout_marginTop="270dp"
        />

</RelativeLayout>

package com.laboratory_control.yang;

import java.util.LinkedList;
import java.util.List;

import android.app.Activity;
import android.app.Application;

public class ExitApplication extends Application {
    private List<Activity> activityList = new LinkedList<Activity>();
    private static ExitApplication instance;
    private ExitApplication()
    {

    }
    //单例模式中获取唯一的ExitApplication实例
    public static ExitApplication getInstance()
    {
        if(null==instance)
        {
            instance=new ExitApplication();
        }
        return instance;
    }
    //添加Activity到容器中
    public void addActivity(Activity activity)
    {
        activityList.add(activity);
    }
    //遍历所有Activity并finish
    public void exit()
    {
        for(Activity activity:activityList)
        {
            activity.finish();
        }
        System.exit(0);
    }
}

package com.laboratory_control.yang;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;

public class Control extends MainActivity {
    boolean door_lamp = true;
    boolean room_lamp = true;
    boolean door = true;
    ImageButton door_ImageButton;//门口灯按钮
    ImageView doorlampImageView;//门口灯图片
    ImageButton room_ImageButton;//门口灯按钮
    ImageView roomlampImageView;//门口灯图片
    ImageButton controlroom_ImageButton;//门按钮
    ImageView doorImageView;//门图片
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.control_main);

        door_ImageButton = (ImageButton) findViewById(R.id.door_ImageButton);
        doorlampImageView = (ImageView) findViewById(R.id.DoorLamp_ImageView);

        room_ImageButton = (ImageButton) findViewById(R.id.room_ImageButton);
        roomlampImageView = (ImageView) findViewById(R.id.roomLamp_ImageView);

        controlroom_ImageButton = (ImageButton) findViewById(R.id.Control_door_ImageButton);
        doorImageView = (ImageView) findViewById(R.id.door_ImageView);
        /**
         * 门口灯按钮监听
         */
        door_ImageButton.setOnClickListener(door_ImageButton_Listener);
        /**
         * 屋里灯按钮监听
         */
        room_ImageButton.setOnClickListener(room_ImageButton_Listener);
        /**
         * 门按钮监听
         */
        controlroom_ImageButton.setOnClickListener(controlroom_ImageButton_Listener);
         /**
         * 为完全退出应用程序而加的代码
         */
        ExitApplication.getInstance().addActivity(this);
    }
    /**
     * 门口灯按钮监听事件
     */
    private OnClickListener door_ImageButton_Listener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (door_lamp) //打开门口灯
            {
                door_lamp = false;
                try
                {
                    //获取输出流
                    outputStream = socket.getOutputStream();
                    //发送数据
                    outputStream.write("3".getBytes());
                    Toast.makeText(Control.this, "已发送打开门口灯命令", Toast.LENGTH_SHORT).show();
                    doorlampImageView.setImageResource(R.drawable.liangdeng);
                }
                catch (Exception e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else //关闭门口灯
            {
                door_lamp = true;
                try
                {
                    //获取输出流
                    outputStream = socket.getOutputStream();
                    //发送数据
                    outputStream.write("4".getBytes());
                    Toast.makeText(Control.this, "已发送关闭门口灯命令", Toast.LENGTH_SHORT).show();
                    doorlampImageView.setImageResource(R.drawable.heideng);
                }
                catch (Exception e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };
    /**
     * 屋里灯按钮监听事件
     */
    private OnClickListener room_ImageButton_Listener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (room_lamp) //打开屋里灯
            {
                room_lamp = false;
                try
                {
                    //获取输出流
                    outputStream = socket.getOutputStream();
                    //发送数据
                    outputStream.write("5".getBytes());
                    Toast.makeText(Control.this, "已发送打屋里灯灯命令", Toast.LENGTH_SHORT).show();
                    roomlampImageView.setImageResource(R.drawable.liangdeng);
                }
                catch (Exception e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else //关闭屋里灯
            {
                room_lamp = true;
                try
                {
                    //获取输出流
                    outputStream = socket.getOutputStream();
                    //发送数据
                    outputStream.write("6".getBytes());
                    Toast.makeText(Control.this, "已发送关闭屋里灯命令", Toast.LENGTH_SHORT).show();
                    roomlampImageView.setImageResource(R.drawable.heideng);
                }
                catch (Exception e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };
    /**
     * 门按钮监听事件
     */
    private OnClickListener controlroom_ImageButton_Listener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (door) //打开门
            {
                door = false;
                try
                {
                    //获取输出流
                    outputStream = socket.getOutputStream();
                    //发送数据
                    outputStream.write("1".getBytes());
                    Toast.makeText(Control.this, "已发送打开门命令", Toast.LENGTH_SHORT).show();
                    doorImageView.setImageResource(R.drawable.men222);
                }
                catch (Exception e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else //关闭门
            {
                door = true;
                try
                {
                    //获取输出流
                    outputStream = socket.getOutputStream();
                    //发送数据
                    outputStream.write("2".getBytes());
                    Toast.makeText(Control.this, "已发送关闭门命令", Toast.LENGTH_SHORT).show();
                    doorImageView.setImageResource(R.drawable.men111);
                }
                catch (Exception e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };
    protected void dialog() {
         AlertDialog.Builder builder = new Builder(Control.this);
         builder.setMessage("亲,您是想?");
         builder.setTitle("提示");
         builder.setPositiveButton("直接退出",
          new android.content.DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
           dialog.dismiss();
           /**
            * 完全退出应用程序
            */
           ExitApplication.getInstance().exit();
           }
          });
         builder.setNegativeButton("返回上一层",
          new android.content.DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
           dialog.dismiss();
           Control.this.finish();
           }
          });
         builder.create().show();
        }
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
          dialog();
          return false;
         }
         return false;
        }
}

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    >

    <!-- 门口灯按钮 -->
    <ImageButton
        android:id="@+id/door_ImageButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginRight="30dp"
        android:layout_marginTop="5dp"
        android:background="@android:color/black"
        android:src="@drawable/gnome_panel_force_quit" />

    <!-- 门口灯图片 -->
    <ImageView
        android:id="@+id/DoorLamp_ImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="16dp"
        android:background="@android:color/white"
        android:src="@drawable/heideng" />

    <!-- 屋里灯按钮 -->
    <ImageButton
        android:id="@+id/room_ImageButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="155dp"
        android:layout_alignRight="@id/door_ImageButton"
        android:background="@android:color/black"
        android:src="@drawable/gnome_panel_force_quit" />

    <!-- 屋里灯灯图片 -->
    <ImageView
        android:id="@+id/roomLamp_ImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@id/DoorLamp_ImageView"
        android:layout_marginTop="150dp"
        android:background="@android:color/white"
        android:src="@drawable/heideng" />

    <!-- 门口灯开关 -->
    <TextView
        android:text="门口灯控制"
        android:textColor="@android:color/holo_green_dark"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="35dp"
        android:layout_centerHorizontal="true"
        />
     <!-- 屋里灯开关 -->
    <TextView
        android:text="屋里灯控制"
        android:textColor="@android:color/holo_green_dark"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="190dp"
        android:layout_centerHorizontal="true"
        />
     <!-- 门控制按钮 -->
    <ImageButton
        android:id="@+id/Control_door_ImageButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="305dp"
        android:layout_alignRight="@id/door_ImageButton"
        android:background="@android:color/black"
        android:src="@drawable/gnome_panel_force_quit" />
    <!-- 门开关 -->
    <TextView
        android:text="门控制"
        android:textColor="@android:color/holo_green_dark"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="337dp"
        android:layout_centerHorizontal="true"
        />
    <!-- 门图片 -->

    <ImageView
        android:id="@+id/door_ImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@id/DoorLamp_ImageView"
        android:layout_alignTop="@+id/Control_door_ImageButton"
        android:background="@android:color/white"
        android:src="@drawable/men111" />

</RelativeLayout>

权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.laboratory_control.yang"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="21" />

    <!--     获取手机信息权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/a333333"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Control"
            android:label="Control"
            ></activity>
    </application>

</manifest>

用到的图片就不贴了

其实只要看过前几片文章,做这个绝对没问题。

我还在程序里设置了申请密码,读手机的IMEI号 ,然后做了一些运算后当成登陆密码,(运算方法只有我和信任的人自己知道,凡是想用这款软件控制实验室,必须通过我们对他的手机的IMEI号进行运算后才可以得到登陆密码)我是为了保证每个人的手机安装软件后都有自己单独的登陆密码,防止其他人安装软件后就可以控制实验室。

上面有运算过程,我已经修改了。防止意外,若有问题QQ946029359

软件可以在上搜索实验室

关于密码列如我的手机

取前六位863328除6 =143888然后减一 = 143887

因为路由器的公网IP会变,可以用花生壳申请一个域名,这样登陆的时候输入域名就行了.解决公网IP会变的麻烦..这是网友云霄(QQ名称)告诉我的..谢谢他

原文地址:https://www.cnblogs.com/pilink/p/8434859.html

时间: 2024-08-06 09:01:54

【转载】android客服端+eps8266+单片机+路由器之远程控制系统的相关文章

Android客服端和Php服务端互通,实现一套应用市场(含服务端)!

Android客服端和Php服务端互通,实现一套应用市场(含服务端) 真正的商城项目,由于个人原因无力继续下去了,代码是几个月前写的,现在放出.基本的功能都有,由于此项目不完整,我也不做多的介绍了.自己去发现吧. 服务端地址:http://dengxiaohua.hk127.wsdns.cc/app/ 后台无需输入账号和密码,直接登录即可. 下载地址:http://www.devstore.cn/code/info/822.html 运行截图:   

瘦客户端和富客服端

今天看webservice的时候看到了这个这个瘦客服端的,之前没有听说过,所以专门去查了一些资料的解释 1 瘦客服端 瘦客户端(Thin Client)指的是在客户端-服务器网 络体系中的一个基本无需应用程序的计算机终端. 它通过一些协议和服务器通信,进而接入局域网.作为应用程序平台的Internet的到来为企业应用程序提供了一个全新的领域:一个基于 Internet/intranet的应用程序运用一个只包含一个浏览器的瘦客户端.这个浏览器负责解释.显示和处理应用程序的图形用户界面(GUI)和它

服务器端 和 客服端 通信的 疑问点记录

为什么作为服务器端的电脑必须有唯一的ip地址,而又为什么客服端的电脑不受唯一的ip地址限制呢? MAC地址有局限性,如果两台电脑不在同一个子网络,就无法知道对方的MAC地址(MAC地址是广播机制找到的 也就是发送一个ip附加上MAC :FF FF FF FF FF FF  对应ip的主机收到后才会返回mac地址数据  但是只能在一个子网络进行广播) 访问某一不在一个子网络的网络资源时候 请求的只是一个ip地址 没有附加要访问服务器的MAC地址 但是同时会把自身的ip地址 和 MAC地址附加上到请

TCP/IP网络编程 学习笔记_7 --基于UDP的服务端/客服端

理解UDP UDP套接字的特点:在笔记2中讲套接字类型有提,类似信件或邮件的传输.UDP在数据传输过程中可能丢失,如果只考虑可靠性,TCP的确比UDP好.但UDP在结构上比TCP更简洁.UDP没有ACK,SEQ那样的操作,因此,UDP的性能有时比TCP高出很多.编程中实现UDP也比TCP简单.另外,虽然UDP是不可靠的数据传输,但也不会像想象中那么频繁地发生数据丢失.因此,在更重视性能而非可靠性的情况下(如传输视频,音频时),UDP是一种很好的选择.而如果是传递压缩文件则必须要用TCP,因为压缩

C# 向服务器上传文件(客服端winform、服务端web)

转载 首先写客服端,winform模拟一个post提交: /// <summary> /// 将本地文件上传到指定的服务器(HttpWebRequest方法) /// </summary> /// <param name="address">文件上传到的服务器</param> /// <param name="fileNamePath">要上传的本地文件(全路径)</param> /// <

Python网络编程UDP服务器与客服端简单例子

[转载] https://blog.csdn.net/hu330459076/article/details/7868028 UDP服务器代码: #!/usr/bin/env python # -*- coding:UTF-8 -*- from socket import * from time import ctime HOST = '127.0.0.1' PORT = 21567 BUFSIZE = 1024 ADDR = (HOST,PORT) udpSerSock = socket(AF

CXF 客服端调用报错

服务端已经发布了WSDL,现在在客服端生成web service客服端代码,在eclipse中新建一个project,然后new->web services->web service client生产客户端代码 在调用的时候报如下错误 解决:缺少axis相应的jar包,加入包: <dependency> <groupId>axis</groupId> <artifactId>axis</artifactId> <version&

Live555 分析(三):客服端

live555的客服端流程:建立任务计划对象--建立环境对象--处理用户输入的参数(RTSP地址)--创建RTSPClient实例--发出DESCRIBE--发出SETUP--发出PLAY--进入Loop循环接收数据--发出TEARDOWN结束连接. 可以抽成3个函数接口:rtspOpen rtspRead rtspClose. 首先我们来分析rtspOpen的过程: int rtspOpen(rtsp_object_t *p_obj, int tcpConnect) { ... ... TRA

mvc 防止客服端多次提交

但凡web开发中都会有户多次点击了提交按钮导致多次提交的情况,一般的集中做法 1.通过js在用户点击的时候将按钮disabled掉,但是这样并不是很可靠(我就可以跳过这个,用一个for循环 我直接自己post数据过去) 2.在生成客服端html的时候存放一个隐藏的input,input里面存放一个随机生成的值(一般为guid),服务器端会将此值保存,等用户提交的时候 判断提交过来的guid是否匹配(这种方法相对第一种安全性更高,但是如果是全静态的页面的话就不满足了,于是自己琢磨了第3中解决方案)