精华内容
下载资源
问答
  • WiFi通信

    千次阅读 2019-03-23 19:27:49
    1、WiFi技术简介 1)概念:Wifi全称Wireless Fidelity(无线保真),实质上是一种商业认证,具有Wi-Fi认证的产品符合IEEE 802.11无线网络规范,它是当前应用最为广泛的WLAN标准,采用2.4G和5G两个频谱下。WiFi是WLAN...

    1、WiFi技术简介
    1)概念:Wifi全称Wireless Fidelity(无线保真),实质上是一种商业认证,具有Wi-Fi认证的产品符合IEEE 802.11无线网络规范,它是当前应用最为广泛的WLAN标准,采用2.4G和5G两个频谱下。WiFi是WLAN中的一种技术, 但很多时候都把Wi-Fi等同于WLAN理解。Wi-Fi (Wireless Fidelity),无线保真技术与蓝牙技术一样,同属于在办公室和家庭中使用的短距离无线技术。该技术使用的是2.4GHz附近的频段,该频段目前尚属没用许可的无线频段。其目前可使用的标准有两个,分别是IEEE802.11a和IEEE802.11b。
    2)特点:最大数据传输速率为11Mbps,也可根据信号强弱把传输率调整为5.5Mbps、2Mbps和1Mbps带宽。室外无障碍物的传输范围为可达300米,室内有障碍的情况下最大100米,是现在使用最多的传输协议。
    在这里插入图片描述
    在这里插入图片描述
    注:QoS(Quality of Service,服务质量)指一个网络能够利用各种基础技术,为指定的网络通信提供更好的服务能力, 是网络的一种安全机制, 是用来解决网络延迟和阻塞等问题的一种技术。 在正常情况下,如果网络只用于特定的无时间限制的应用系统,并不需要QoS,比如Web应用,或E-mail设置等。但是对关键应用和多媒体应用就十分必要。当网络过载或拥塞时,QoS 能确保重要业务量不受延迟或丢弃,同时保证网络的高效运行。
    3)发展历程:
    在这里插入图片描述
    在这里插入图片描述
    WLAN与WIFI的区别:
    WLAN全称为:Wireless Local Area Networks,中文解释为:无线局域网络,是一种利用射频(Radio Frequency RF)技术进行数据传输的系统,该技术的出现绝不是用来取代有线局域网络,而是用来弥补有线局域网络之不足,以达到网络延伸之目的,使得无线局域网络能利用简单的存取架构让用户透过它,实现无网线、无距离限制的通畅网络。WIFI就是WLANA(无线局域网联盟)的一个商标,该商标仅保障使用该商标的商品互相之间可以合作,与标准本身实际上没有关系,但因为WIFI 主要采用802.11b协议,因此人们逐渐习惯用WIFI来称呼802.11b协议。从包含关系上来说,WIFI是WLAN的一个标准,WIFI包含于 WLAN中,属于采用WLAN协议中的一项新技术。

    2、WiFi组建方法:
    一般架设无线网络的基本配备就是无线网卡及一台AP,如此便能以无线的模式,配合既有的有线架构来分享网络资源,架设费用和复杂程度远远低于传统的有线网络。如果只是几台电脑的对等网,也可不要AP,只需要每台电脑配备无线网卡。AP为AccessPoint简称,一般翻译为“无线访问节点”,或“桥接器”。它主要在媒体存取控制层MAC中扮演无线工作站及有线局域网络的桥梁。有了AP,就像一般有线网络的Hub一般,无线工作站可以快速且轻易地与网络相连。特别是对于宽带的使用,WiFi更显优势,有线宽带网络(ADSL、小区LAN等)到户后,连接到一个AP,然后在电脑中安装一块无线网卡即可。普通的家庭有一个AP已经足够,甚至用户的邻里得到授权后,则无需增加端口,也能以共享的方式上网。
    注:AP与无线路由器的区别:AP即无线接入点,分为单纯性AP和有路由功能的AP,后者即为无线路由器。

    3、Wifi网络的体系结构:
    根据组网方法,分为三种:无中心网络、有中心网络和ESS LAN。
    在这里插入图片描述
    在这里插入图片描述
    注:Ad Hoc模式:即点对点模式,是自组网模式,各个点都是平等的,任意一点均可以和其他节点进行通信,不需要中心点;Infrastructure模式无线局域网是指通过AP互连工作模式,把AP看做传统局域网中集线器功能,Infrastructure 时无线设备(如手机,本子)是作为从设备连接到路由(ap)上的。

    4、WiFi IEEE 802.11协议
    1)802.1标准的四种主要组件:
    工作站(Station):构建网络的主要目的是为了在工作站间传送数据。所谓工作站,是指配备无线网络接口的计算设备。
    接入点(Access Point):802.11网络所使用的帧必须经过转换,方能被传递至其他不同类型的网络。具备无线至有线的桥接功能的设备称为接入点,接入点的功能不仅于此,但桥接最为重要。
    无线媒介(Wireless Medium):802.11标准以无线媒介在工作站之间传递帧。其所定义的物理层不只是一种,802.11最初标准化了两种射频物理层以及一种红外线物理层。
    分布式系统(Distribution System):当几个接入点串联以覆盖较大区域时,彼此之间必须相互通信以掌握移动式工作站的行踪。分布式系统属于802.11的逻辑组件,负责将帧转送至目的地。
    2)分层结构:802.11协议定义了WLAN物理层以及MAC层的协议标准。
    注:网上有两种版本,现以第二种版本来作说明。

    在这里插入图片描述

    物理层:
    物理层由三部分组成:物理层管理层、 物理层会聚协议(PLCP) 和物理介质依赖子层(PMD)。物理层的功能:①载波监听:为MAC层提供物理载波监听功能;避免数据冲突;通过PMD实现介质状态检查和载波监听。②提供接口:实现数据帧比特流的传送与接收;通过PICP实现接收,将PMD转换为传输模式;发送完成后,关闭发送器,PMD转换为接收模式。③提供信号载波:使数据可以传输在无线介质上。

    PLCP子层帧格式:
    在这里插入图片描述
    MAC层CAMA机制:
    在这里插入图片描述
    MAC层(媒体访问控制子层)功能:
    ①访问控制功能:分布式协调功能(DCF):竞争获取访问权;基于CSMA/CA;点协调功能(PCF):无竞争传送方式;AP进行轮询,站点在轮询到时才能传输。
    ②网络连接功能:通过被动或主动方式加入AP。
    ③寻址和帧识别功能:在LLC(逻辑连接控制子层)层的支持下执行。
    ④身份验证和数据加密:保证无线网络身份的确认、访问的安全。
    数据链路层由两部分组成:逻辑连接控制子层(LLC)、媒体访问控制子层(MAC)。
    MAC层的帧分类:
    ① 数据帧:负责将MSDU传输到目标站,转变给相应的LLC层。
    ② 控制帧:在工作站和AP之间建立连接并认证后提供辅助功能,包括RTS帧、CTS帧和ACK帧等。
    ③ 管理帧:负责在工作站和AP之间建立初始通信、提供连接或认证等。包括Probe Requesst/Response帧(主动扫描时)、Beacon帧(信标帧,被动扫描时AP发出)、ReAssociation Request/Response帧(从ESS的一个BSS漫游到另一个BSS进行重新关联,以便新AP联系老AP取得原来的关联信息)。

    5、Wifi传输认证过程:
    1)无线扫描:用户接入过程首先需要通过主动/被动扫描,再通过认证和关联两个过程后才能和AP建立连接。
    2)认证过程:为防止非法用户接入,首先需要在用户和AC/FATAP/Gateway之间建立认证,认证机制包括两种。只有通过认证后才能进入关联阶段。
    无加密认证:以 SSID (Service Set ID)作为最基本的认证方式。包括开放系统认证和封闭系统认证两种
    共享密钥认证:使用共享密钥的方式进行身份认证,采用WEP(Wired Equivalent Privacy)密钥作为共享密钥。
    3)关联过程:如果用户想通过AP接入无线网络,用户必须同特定的AP关联。当用户通过指定SSID选择无线网络,并通过AP认证后,就可以向AP发送关联请求帧。AP将用户信息添加到数据库,向用户回复关联响应。用户每次只可以关联到一个AP上,并且关联总是由用户发起。
    注:AC的概念:它是指无线接入控制服务器(AC), 接入控制器(AC) 无线局域网接入控制设备,负责把来自不同AP的数据进行汇聚并接入Internet,同时完成AP设备的配置管理、无线用户的认证、管理及宽带访问、安全等控制功能;Fat模式是传统的WLAN组网方案,无线AP本身承担了认证终结、漫游切换、动态密钥产生等复杂功能,相对来说AP的功能较重,因此称为Fat AP。Gateway网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。

    展开全文
  • android的wifi通信示例的服务端 android的wifi通信示例的服务端 android的wifi通信示例的服务端 android的wifi通信示例的服务端
  • 基于WiFi模块的Android WiFi通信

    万次阅读 多人点赞 2018-07-18 16:17:01
    基于ESP8266的Android WiFi通信广泛应用于物联网领域,常用是通过局域网实现Android端和下位机的通信,达到控制目的。 此篇文章记录的内容,需要手机连接到WiFi模块,通过wifi让Android端和硬件部分处于同一个...

    通过一段时间的学习和应用,理解了Android通信,通过这篇文章记录一下学习过程。

    基于ESP8266的Android WiFi通信广泛应用于物联网领域,常用是通过局域网实现Android端和下位机的通信,达到控制目的。

    此篇文章记录的内容,需要手机连接到WiFi模块,通过wifi让Android端和硬件部分处于同一个局域网内。Android网络通信通过socket编程实现网络的连接,通过IO流实现数据的发送与接收。

    首先,创建一个Android项目,首先,需要给予APP网络权限:

     <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

    第二步,创建一个类SendThead,内容为发送和接收的代码,首先定义IP,端口port,以及接收/发送’变量,打开套接字实现网络的连接,连接结束关闭套接字,采取多线程实现信息的发送与接收:

    package com.example.a14942.smart_see;
    
    /**
     * Created by 14942 on 2018/3/26.
     */
    
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.ArrayList;
    
    class SendThread implements Runnable {
    
        private String ip;
        private int port;
        BufferedReader in;
        PrintWriter out;      //打印流
        Handler mainHandler;
        Socket s;
        private String receiveMsg;
    
        ArrayList<String> list = new ArrayList<String>();
    
        public SendThread(String ip,int port, Handler mainHandler) {     //IP,端口,数据
            this.ip = ip;
            this.port=port;
            this.mainHandler = mainHandler;
        }
    
        /**
         * 套接字的打开
         */
        void open(){
            try {
                s = new Socket(ip, port);
                //in收单片机发的数据
                in = new BufferedReader(new InputStreamReader(s.getInputStream()));
                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                        s.getOutputStream())), true);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 套接字的关闭
         */
        void close(){
            try {
                s.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
    
            //创建套接字
            open();
    
            //BufferedReader
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(200);
                            close();
                            open();
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        if (!s.isClosed()) {
                            if (s.isConnected()) {
                                if (!s.isInputShutdown()) {
                                    try {
                                        Log.i("mr", "等待接收信息");
    
                                        char[] chars = new char[1024];					//byte[] bys = new byte[1024];		
                                        int len = 0;							//int len = 0;
                                        while((len = in.read(chars)) != -1){				//while((len = in.read(bys)) != -1) {	
                                            System.out.println("收到的消息:  "+new String(chars, 0, len));      in.write(bys,0,len);
                                            receiveMsg = new String(chars, 0, len);				// }
    													
                                            Message msg=mainHandler.obtainMessage();
                                            msg.what=0x00;
                                            msg.obj=receiveMsg;
                                            mainHandler.sendMessage(msg);
                                        }
    
                                    } catch (IOException e) {
                                        Log.i("mr", e.getMessage());
                                        try {
                                            s.shutdownInput();
                                            s.shutdownOutput();
                                            s.close();
                                        } catch (IOException e1) {
                                            e1.printStackTrace();
                                        }
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
    
                    }
                }
    
            });
            thread.start();
    
            while (true) {
    
                //连接中
                if (!s.isClosed()&&s.isConnected()&&!s.isInputShutdown()) {
    
                    // 如果消息集合有东西,并且发送线程在工作。
                    if (list.size() > 0 && !s.isOutputShutdown()) {
                        out.println(list.get(0));
                        list.remove(0);
                    }
    
                    Message msg=mainHandler.obtainMessage();
                    msg.what=0x01;
                    mainHandler.sendMessage(msg);
                } else {
                    //连接中断了
                    Log.i("mr", "连接断开了");
                    Message msg=mainHandler.obtainMessage();
                    msg.what=0x02;
                    mainHandler.sendMessage(msg);
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    try {
                        out.close();
                        in.close();
                        s.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    e.printStackTrace();
                }
            }
    
        }
    
        public void send(String msg) {
            System.out.println("msg的值为:  " + msg);
            list.add(msg);
        }
    
    }
    
    

    第三步,创建主活动,编写布局(xml)文件,这里我创建了一个温度显示框,和两个开关控制按钮(switch控件):

    <?xml version="1.0" encoding="utf-8"?>
    <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/screen"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@drawable/bb"
        >
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_x="30dp"
            android:layout_y="130dp"
            android:orientation="horizontal">
    
    
            <TextView
                android:id="@+id/textView2"
                android:layout_width="50sp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="33px"
                android:text="湿度"
                android:textColor="#000000"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/ttv2"
                android:layout_width="160sp"
                android:layout_height="wrap_content"
                android:background="#FFFFFF"
                android:text=""
                android:textSize="18sp" />
    
            <TextView
                android:layout_width="60sp"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:paddingLeft="10px"
                android:text="%rh"
                android:textColor="#000000"
                android:textSize="18sp" />
    
        </LinearLayout>
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开         关"
            android:textColor="#000000"
            android:textSize="18sp"
            android:layout_x="50dp"
            android:layout_y="200dp"
            />
    
        <Switch
            android:id="@+id/Switch2"
            android:layout_width="50sp"
            android:layout_height="wrap_content"
            android:layout_weight="1.01"
            android:layout_x="210dp"
            android:layout_y="270dp" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="自动手动"
            android:textColor="#000000"
            android:textSize="18sp"
            android:layout_x="50dp"
            android:layout_y="270dp"
            />
    
        <Switch
            android:id="@+id/Switch1"
            android:layout_width="50sp"
            android:layout_height="wrap_content"
            android:layout_x="210dp"
            android:layout_y="200dp" />
    
    </AbsoluteLayout>

     第四步,编写主活动,包括实现网络连接(SendThead),实现消息的发送和接收,对开关控件(switch)定义点击事件:

    package com.example.a14942.smart_see;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.CompoundButton;
    import android.widget.Switch;
    import android.widget.TextView;
    
    import java.io.BufferedReader;
    import java.io.PrintWriter;
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity{
    
        /*接收发送定义的常量*/
        private String mIp = "192.168.4.1";
        private int mPort = 9000;
        private SendThread sendthread;
        String receive_Msg;
        String l;
        String total0,total1,total2,total3;
        private Button button0;
        private Button button1;
        static PrintWriter mPrintWriterClient = null;
        static BufferedReader mBufferedReaderClient	= null;
        Switch switch1,switch2;
        /*****************************/
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //getSupportActionBar().hide();
            setContentView(R.layout.activity_main);
    //        button0= (Button)findViewById(R.id.Water_W_N);
    //        button0.setOnClickListener(button0ClickListener);
    //        button1= (Button)findViewById(R.id.Water_W_O);
    //        button1.setOnClickListener(button1ClickListener);
    
            /***************连接*****************/
            sendthread = new SendThread(mIp, mPort, mHandler);
            Thread1();
            new Thread().start();
            /**********************************/
    
            switch1 = (Switch) findViewById(R.id.Switch1);
            switch1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    
                @Override
                public void onCheckedChanged(CompoundButton buttonView,
                                             boolean isChecked) {
                    // TODO Auto-generated method stub
                    if (isChecked) {
                        sendthread.send("A");
                    } else {
                        sendthread.send("B");
                    }
                }
    
            });
    
            switch2 = (Switch) findViewById(R.id.Switch2);
            switch2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    
                @Override
                public void onCheckedChanged(CompoundButton buttonView,
                                             boolean isChecked) {
                    // TODO Auto-generated method stub
                    if (isChecked) {
                        sendthread.send("C");
                    } else {
                        sendthread.send("D");
                    }
                }
    
            });
        }
    //    private View.OnClickListener button0ClickListener = new View.OnClickListener() {
    //        public void onClick(View arg0) {
    //            mPrintWriterClient.print("j");
    //            mPrintWriterClient.flush();
    //
    //        }
    //    };
    //    private View.OnClickListener button1ClickListener = new View.OnClickListener() {
    //        public void onClick(View arg0) {
    //            mPrintWriterClient.print("m");
    //            mPrintWriterClient.flush();
    //        }
    //    };
    
    
        private class FragmentAdapter extends FragmentPagerAdapter {
            List<Fragment> fragmentList = new ArrayList<Fragment>();
    
            public FragmentAdapter(FragmentManager fm, List<Fragment> fragmentList) {
                super(fm);
                this.fragmentList = fragmentList;
            }
    
            @Override
            public Fragment getItem(int position) {
                return fragmentList.get(position);
            }
    
            @Override
            public int getCount() {
                return fragmentList.size();
            }
    
        }
    
    
        /*接收线程*******************************************************************************/
        /**
         * 开启socket连接线程
         */
        void Thread1(){
    //        sendthread = new SendThread(mIp, mPort, mHandler);
            new Thread(sendthread).start();//创建一个新线程
        }
    
        Handler mHandler = new Handler()
        {
            public void handleMessage(Message msg)
            {
                TextView text0 = (TextView)findViewById(R.id.ttv2);
                super.handleMessage(msg);
                if (msg.what == 0x00) {
    
                    Log.i("mr_收到的数据: ", msg.obj.toString());
                    receive_Msg = msg.obj.toString();
                    l = receive_Msg;
                    text0.setText(l);
                }
            }
        };
    }
    

    这样,一个简单的物联网通信就实现了。希望对大家有所帮助,如有疑问,欢迎留言。

    本次文章一样的源码暂时找不到了,附上依托以上的代码开发的简单的demo示例

    csdn:https://download.csdn.net/download/weixin_40042248/13456038

    github:https://github.com/Yang-Jianlin/ESP8266-with-Android

    展开全文
  • Android WIFI通信scoket通信聊天室WiFi互传文件WiFi热点开启,通过建立WiFi热点,启动scoket服务器和服务器进行互相传输文件聊天等,服务器、客户端再同一APP内,可装在2个手机里分别启动服务器和客户端。
  • android 的wifi通信示例 android 的wifi通信示例 android 的wifi通信示例 android 的wifi通信示例
  • 全链路产品智能化iot平台,WIFI通信的Android案例,在博客中有详细介绍,此为博客示例代码。
  • WIFI通信测试案例,包括功能测试、适应性测试、稳定性测试、兼容性测试、性能测试
  • WiFi通信的安全分析

    2011-03-12 23:30:28
    WiFi通信的安全分析,WiFi通信的安全分析,WiFi通信的安全分析,WiFi通信的安全分析,WiFi通信的安全分析,WiFi通信的安全分析,WiFi通信的安全分析,WiFi通信的安全分析,
  • stm32实现简单wifi通信

    万次阅读 多人点赞 2019-04-14 15:54:50
    最近需要做wifi通信实验,实验中的坑比较多,本文章用于记录实验中遇到的问题。 实验内容 了解ESP8266的基本工作原理,使程序能够自行连接给定的WIFI热点和服务器并实现双向通信。 工程文件网盘地址:...

    最近需要做wifi通信实验,实验中的坑比较多,本文章用于记录实验中遇到的问题。
    ----------更新:本文章只实现了简单的wifi连接功能,最近封装了较完整的wifi协议,能够实现wifi连接、服务器连接、封装发送数据、解析接收数据、服务器创建等功能,文章链接:https://blog.csdn.net/qq_26024785/article/details/107352408

    实验内容

    了解ESP8266的基本工作原理,使程序能够自行连接给定的WIFI热点和服务器并实现双向通信。
    工程文件网盘地址:https://pan.baidu.com/s/11HxmfvIRzxYGAoqXzZa0Uw 提取码:hbv2

    整体思路

    通过直接控制wifi模块可以发现整个连接过程有几个指令是不可缺少的:

    1. AT测试、
    2. AT+CWMODE=1设置工作模式、
    3. AT+CWJAP=“热点名称”,“热点密码”
    4. AT+CIPSTART=“TCP”,“服务器地址”,端口号

    另外为了方便测试还有ATE1打开回显。
    根据以上命令编写wifi_init()函数,先向wifi模块发送“AT”,接收到OK后发送“AT+CWMODE=1”,接收到OK后一次发送3、4两条命令同时检测是否接收到OK。
    在上述任意环节超出超时时间后还没有检测到OK则认为连接失败,进行下一次连接,连续连接失败3次后返回错误信息。

    代码解析

    wifi模块参数配置:

    #define WIFI_NAME "hello_world"			//需要连接的热点名
    #define WIFI_PWD "87654321"					//热点密码
    #define SERVER_ADDR "192.168.43.73"		//服务器IP地址
    #define SERVER_PORT "5656"						//端口号
    

    此代码段在my_func.h中4-7行,将其中的参数改成自己的热点及服务器信息。

    wifi初始化程序:

    int wifi_init()
    {
    	uint8_t ret=0;
    	
    	ret = Send_AT_commend("AT", "OK", 100);
    	if(!ret)
    		return -1;
    	#ifdef DEBUG
    		Send_AT_commend("ATE1", "", 100);
    	#else
    		Send_AT_commend("ATE0", "", 100);
    	#endif
    	ret = Send_AT_commend("AT+CWMODE=1", "OK", 100);
    	if(!ret)
    		return -2;
    	wifi_str();
    	ret = Send_AT_commend(temp, "OK", 9000); 			//AT+CWJAP="pxc002","?????"
    	if(!ret)
    		return -3;
    	server_str();
    	ret = Send_AT_commend(temp, "OK", 3000);			//AT+CIPSTART="TCP","192.168.31.32",3456
    	if(!ret)
    		return -4;
    	return 1;
    }
    

    #ifdef到#endif之间的代码为开关AT指令回显,去掉后对程序功能无影响。

    发送AT指令函数:

    uint8_t Send_AT_commend(char *at_commend, char *re_commend, uint16_t time_out)
    {
    	uint8_t i=0;
    	for(i=0;i<3;i++)
    	{
    		clear_buf();											//清空接收数组
    		HAL_UART_Transmit(&huart1, (uint8_t *)at_commend, strlen(at_commend), 0xFFFF);
    		HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", 2, 0xFFFF);				//发送回车换行
    		HAL_Delay(time_out);
    		if(find_str(re_commend))
    			return 1;
    		i++;
    	}
    	return 0;
    }
    

    此函数接收三个参数,分别为需要发送的AT指令、期待的返回数据、超时时间。
    发送AT指令前先将my_re_buf1清空,防止对之前的数据误判,然后发送AT指令并发送回车换行,延时time_out,通过find_str()函数查找开发板是否接收到了wifi模块发来的OK,检测到则返回1,否则i++再发送一次,三次都没有检测到的话就返回0。

    定时器中断回调程序:

    while(send_buf[i])send_buf[i++]=0x00;			//清空send_buf数组
    while(pt_r2<pt_w2 )
    {
    	//HAL_UART_Transmit(&huart1,&my_re_buf2[pt_r2++],1,1000);				
    	while(pt_r2<pt_w2)
    		send_buf[len++]=my_re_buf2[pt_r2++];
    	wifi_send(send_buf,len);
    }
    

    将demo中的程序注释掉,改成自己的以便实现PC通过板子向服务器发送数据。当pt_r2<pt_w2时,将my_re_buf2中新接收到的数据拷贝到send_buf数组中,再调用wifi_send()函数发送数据。

    发送数据函数:

    void wifi_send(uint8_t *buf, int len)
    {
    	char len_str[]="",temp1[256]="";
    	itoa(len, len_str);
    	strcat(temp1,"AT+CIPSEND=");
    	strcat(temp1,len_str);
    	HAL_UART_Transmit(&huart2, (uint8_t *)"发送数据\r\n", 10, 0xFFFF);
    	if(Send_AT_commend(temp1, ">", 300))
    		if(Send_AT_commend((char *)buf, "SEND OK", 300))
    			HAL_UART_Transmit(&huart2, (uint8_t *)"发送成功!!!\r\n", 16, 0xFFFF);
    }
    

    此函数接收两个参数,分别为需要发送的字符串数组、发送字节数。
    通过tioa()函数将整数len转换为字符串,并通过strcat将temp1拼接成AT+CIPSEND=len。Send_AT_commend()发送字符串temp1,在接收到“>”后发送字符串buf,接收到“SEND OK”则发送成功。

    踩到的坑

    strstr()函数:

    strstr(s1,s2)函数接收两个字符串参数,具体功能是检测s2是否是s1的子集,是的话返回s2首次出现的地址,否则返回NULL。但是这个函数里面有个硬性bug,如果s1[]={0x00, ‘a’, ‘b’, ‘c’} s1[]={‘a’},strstr(s1,s2)执行后返回NULL,也就是说strstr函数执行的结束标志是s1数组的0x00。这个bug坑了我两个多小时!!!

    指针传值问题:

    在C语言程序中需要计算字符串数组s的长度通常会用到sizeof或者strlen函数,但是如果char *p=s的话sizeof§和strlen§得到的数据都不是s的长度,具体解释是p虽然指向s数组的首地址,但是p不含有s数组后面的数据,因为以上两个函数无法通过指针p获取s的长度。

    总结

    C语言基础知识掌握的扎实真的很重要,否则会像我这样遇到许多很智障的bug。由于写此工程时利用的是零碎的空闲时间且比较仓促,没有做充足的实验验证,因此工程还有一些隐藏和没有解决的bug,比如发送数据时总是会丢失第一个字节(但是发送数据前加一个空格能够完美解决,至于为什么我也不知道,懒得解决了就这样吧) (此bug已解决)。所以工程仅供学习交流,切勿用于生产。

    原文地址: https://www.jhxblog.cn/article/?articleid=1

    展开全文
  • 针对煤矿信息化发展对矿井通信系统网络扩展性、兼容性和通信速率的需求,介绍了WiFi通信技术的特点,从有线通信网络的延伸、无线调度通信、应急通信、数据采集和控制命令传输等方面分析了WiFi通信技术在煤矿信息化中的...
  • Android项目源码安卓手机之间WIFI通信源码
  • 本文介绍IEEE802.11b的基本技术,给出一种在嵌入式环境中的WiFi通信设计方案;通过一个移动监护系统的具体实现,说明方案的有效性。 关键词 IEEE802.11b嵌入式WiFi TCP/IP 移动监护 目前,IEEE802.11无线局域网标准在...
  • 以榆家梁煤矿43101薄煤层综采工作面为应用背景,从频段选择、网络拓扑、基站布置、快速漫游切换机制等方面提出了应用于薄煤层综采工作面的WiFi通信方案:选择5.8 GHz为 WiFi通信优选频段;该工作面已铺设有线网络,...
  • 之前写过PC与Android之间通过WIFI通信(通过Socket,可以在博客里面搜索),PC作为主机,Android作为客户机,现在手头有一台仪器通过wifi传输数据,如果仪器作为主机发射WIFI热点信号,Android需要连接到该热点才能...
  • 近段时间学习用到了wifi通信,以下为个人关于wifi通信的一些整理:
    wifi所需权限,同样放于application外
    <!-- wifi -->
        <uses-permission android:name="android.permission.INTERNET" ></uses-permission>   允许打开网络套接字
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>   //允许访问关闭wifi
        <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>     //允许改变wifi状态
        <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>        //允许使用电源锁定管理以使进程休眠或屏幕变暗
        <uses-permission android:name="android.permission.RESTART_PACKAGES"></uses-permission>   //允许程序重新启动其他程序
        
    **********************************************************************************************************************************
    首先得了解异步任务:
    类继承extends AsyncTask<Void, Void, Void>
    对象调用execute()开启异步任务

    结构:
    execute  执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
    onPreExecute   在execute被调用后立即执行,一般用来在执行后台任务前对UI做一些标记
    doInBackground  在onPreExecute完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。
                    在执行过程中可以调用publishProgress来更新进度信息。
    onProgressUpdate   在调用publishProgress时,此方法被执行,直接将进度信息更新到UI组件上。
    onPostExecute    当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上

    代码:
    /*构造方法*/
        public ContTask()
        {
            
        }
        
        /*子线程任务*/
        public Void doInBackground(Void... params)
        {
            publishProgress();   //启动更新界面任务
            return null;
        }
        
        /*更新界面任务*/
        public void onProgressUpdate(Void... values)
        {
            
        }
        
    **********************************************************************************************************************************
    关闭异步取消连接
    if (connectTask != null && connectTask.getStatus() == AsyncTask.Status.RUNNING) {      //connectTask为异步对象
                    
                            // 如果Task还在运行,则先取消它
                            connectTask.cancel(true);
                            try {
                                connectTask.getmSocket().close();   //关闭套接字
                            }
                            catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        
    **********************************************************************************************************************************
    连接wifi协议
    Socket mSocket = new Socket();   //实例化socket
    SocketAddress mSocketAddress = new InetSocketAddress(Constant.IP, Constant.port);    //传入ip端口获取网络套接字
    mSocket.connect(mSocketAddress, 3000);   //连接wifi协议

    此时可通过:
    mSocket.getInputStream();// 得到输入流
    mSocket.getOutputStream();// 得到输出流

    **********************************************************************************************************************************
    写命令
    输出流.write(命令);// 写命令  byte类型

    输出流.flush();// 发送并清空内存流

    **********************************************************************************************************************************
    读取命令
    byte[] str = new byte[len];
    输入流.read(str);

    **********************************************************************************************************************************
    写文件:
    public  static String file ;    //文件存储目录和名字
    file = Environment.getExternalStorageDirectory().getCanonicalPath()+"/"+"ywd.txt";    //指定路径要创建文件为ywd.txt

    FileOutputStream  fileoutput = new FileOutputStream(file,true);   //创建文件,true设置为可追加
    String st = "你好:";
    fileoutput.write(st.getBytes());   //写入
    fileoutput.flush();  //刷新文件

    **********************************************************************************************************************************
    读文件:
    FileIntputStream fileintput = new FileInputStream(file);  //打开

    /*读取*/
    byte[] temp = new byte[1024];
    StringBuilder sb = new StringBuilder("");
    int len = 0;
    while((len=fileintput.read(temp)) >0)
    {
        sb.append(new String(temp,0,len));
    }

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,913
精华内容 1,965
关键字:

wifi通信