Socket communication using AT commands for

BC26 foundation supports TCP and UDP protocols carried Socket Communications, the two protocols are supported BC26 numerous communication protocols. This article explains how to use these protocols to communicate with the server. Before learning this article, please use the first AT+CPSMS=0instructions to the power-saving mode (PSM) is closed. Otherwise, every ten seconds, MCU will enter the sleep state, so you have to restart the evaluation board, quite disturbing to learn during the evaluation board has been plugged into the USB port, supply worry, it does not matter power saving mode. All AT commands Socket Communications can be carried out in the AT command set of instructions assistant panel by selecting [command] key BC26 Socket obtain and read the manual.

Commands

We know, TCP is a connection-oriented protocol, TCP sends information to ensure that the other party must be able to receive, even though they can not receive the information in this party can be known. The UDP is a connectionless protocol-oriented, just send information to each other, as the other party can receive, the party does not care about. Next, described herein is first used when using the Socket communication command.

AT+QSOC=<domain>,<type>,<protocol>

Creating a TCP or UDP Socket.

  • <domain>: Indicates the IPv4 or IPv6, where 1 represents IPv4.
  • <type>: Indicates the protocol type, wherein 1 denotes TCP; 2 represents UDP.
  • <protocol>: Indicates the protocol type, wherein 1 denotes IP; 2 represents ICMP.

For example: AT+QSOC=1,1,1it represents the creation of a use IPv4, the use of TCP / IP Socket.

AT+QSOCON=<socket_id>,<remote_port>,<remote_address>

Use Socket for remote connections.

  • <socket_id>: BC26 supports the use of a total of five Socket communication, edited from 0 to 4, wherein the parameter specifies a Socket.
  • <remote_port>: A communication port 0 to 65535.
  • <remote_address>: Remote IP address.

For example: AT+QSOCON=0,5000,"193.112.19.116"represents the number 0 Socket port address 5000 to initiate a connection to the remote server 193.112.19.116.

AT+QSOSEND=<socket_id>,<data_len>,<data>

Send data to the distal end.

  • <socket_id>: Socket number, ranging from 0 to 4.
  • <data_len>: Length of the data, in bytes. For the ASCII code, the length of a character is 1.
  • <data>: Transmitting data using hexadecimal numerals. Remember, whether you send an integer, float, string, or other data types, where all will be digitally represented in 16 bytes. Suppose you want to send a character H, check the ASCII table , find the Hcode is 0x48, is sent to 48. If you want to send is Hello, the content is sent to: 48656C6C6F.

For example: AT+QSOSEND=0,5,48656C6C6Fit represents a number of 0 Socket allows transmission data byte length 5 [0x48,0x65,0x6C, 0x6C, 0x6F].

+QSONMI=<socket_id>,<data_len>

This unsolicited result code data (the URC), that is sent from the active server, rather than the data requested by the client. Represents receives data sent by the server.

  • <socket_id>: That is the first few numbers Socket data received.
  • <data_len>: Indicates the length of the data received.

For example: +QSONMI=0,5represents a number of 0 Socket receive remote transmission over the 5 bytes of data.

+QSORF=<socket_id>,<req_length>

Receive data from Socket. With this command on a command.

  • <socket_id>: Receive data indicating Socket number.
  • <req_length>: Message length data.

For example: AT+QSORF=0,5represents a 5-byte data read from the received data in the buffer number 0 Socket.

AT+QSODIS=<socket_id>

Socket connection is disconnected.

  • <socket_id>Instructed to disconnect the Socket number.

AT+QSOCL=<socket_id>

Close Socket.

  • <socket_id>Instructed to disconnect the Socket number.

NB-IOT usage scenario, a small amount of data must be transmitted per day, so after opening Socket, data transfer should be completed immediately disconnected and closed.

Communicate using the TCP protocol

This section demonstrates how to use AT commands to communicate with a remote server to perform a TCP, on condition that there must be a server with a public IP, not, not experiments, but the problem is not large. Mainly behind the use of a higher level of agreement with Telecom, Huawei, Ali dedicated things cloud communications.

Service-Terminal

Server, set up specific development environment, please refer to the previous article .

TCPSocket create a new folder, enter, use the command dotnet new consoleto create a new console project, the code is as follows:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Text;

namespace TCPSocket
{
    class Program
    {
        static void Main(string[] args)
        {   //设置服务器 IP,如果是腾讯云,必须使用内网地址,而不是公网 IP。
            IPAddress ip = IPAddress.Parse("172.16.0.11");
            IPEndPoint point = new IPEndPoint(ip, 5000); //端口指定为 5000
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                s.Bind(point);
                s.Listen(5);
                Console.WriteLine("服务器开始侦听...");
                Socket subSocket = s.Accept(); //等待新连接,本程序仅能接受一个客户端的连接
                Console.WriteLine("获取一个来自{0}的连接", subSocket.RemoteEndPoint.ToString());
                //创建线程接收客户端的消息
                Task.Factory.StartNew(() => ReceiveMessage(subSocket), TaskCreationOptions.LongRunning);
                //发送消息
                while (true)
                {
                    string sendStr = Console.ReadLine();
                    if(sendStr=="") return; //如果在控制台不输入任何字符直接按回车,则退出程序
                    byte[] sendBuff = Encoding.ASCII.GetBytes(sendStr);
                    subSocket.Send(sendBuff, sendBuff.Length, SocketFlags.None);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                s.Close();
            }
        }

        //监听客户端连接的线程方法
        static void ReceiveMessage(Socket subSocket)
        {
            byte[] buff = new byte[1024]; //创建一个接收缓冲区
            try
            {
                while (true)
                {   
                    int count = subSocket.Receive(buff, buff.Length, SocketFlags.None);
                    //下面这个判断是非常必要的,否则有可能导致不停地接收到长度为 0 的数据,导致 CPU 占用率100%
                    if (count == 0) 
                    {
                        subSocket.Close();
                        return;
                    }
                    //将接收到的数据转化为 ASCII 字符
                    string recvStr = Encoding.ASCII.GetString(buff, 0, count);
                    Console.WriteLine($"接收到数据:{recvStr}");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                subSocket.Close();//客户端关闭时会引发异常,此时关闭此连接
                Console.WriteLine("客户端已退出连接。");
            }
        }
    }
}

This procedure is for testing AT commands, it is relatively simple to write, to achieve the following functions:

  1. Only you can receive a connection, if the reception again, please re-run the program. When the program receives a new connection, the client IP address will be printed.
  2. Upon receiving the message, the message will be converted to an ASCII string printed.
  3. Press enter console input characters, the string can be converted into a byte array to the client, it is noted only accomplish this a connection with the client.
  4. Enter nothing Press Enter to exit the program.

Run the program

  • Server-side use dotnet runto run the program to start the service, "Server starts listening ...."
  • Open AT command assistant, load [TCP Socket] script.
  • Send command: AT+QSOC=1,1,1Create Socket.
  • Send command: AT+QSOCON=0,5000,"193.112.19.116"Connect to the server, pay attention to your own IP address and port changes.
  • Send command: AT+QSOSEND=0,5,48656C6C6Fsend data "Hello", to observe whether the server is received.
  • Send command: AT+QSOSEND=0,10,54435020536F636B6574send data "TCP Socket", observe whether the server is received.
  • The server sends the data abc.
  • The client receives +QSONMI=0,3.
  • Sending instructions: AT+QSORF=0,3receiving a data buffer.
  • The server sends the data good-bye.
  • The client receives +QSONMI=0,8.
  • Sending instructions: AT+QSORF=0,8receiving a data buffer.
  • Sending instructions: AT+QSODIS=0Disconnect.
  • Sending instructions: AT+QSOCL=0Close Socket.

Operation effect as shown in FIG.

Using the UDP protocol to communicate

UDP 协议具有资源消耗小,处理速度快的优点,但它是不靠的。接下来演示使用 UDP 协议进行通信,使用 UDP 和使用 TCP 的思维方式是不一样的。UDP 没有连接,也就没有所谓的断开连接,但有意思的是,使用 AT 指令发送 UDP 信息时,依然和 TCP 一样,需要进行连接和断开连接操作(在 C# 中写 UDP 程序是没有这些的)。你不能说建立一个连接后,在这个连接的基础上你来我往。UDP 的一个 Socket 只会侦听某一端口的所有信息,而这个信息可能是不同客户端发送的,所以,每次接收信息都要创建一个新的IPEndPoint。所以这次我把程序改为将接收到的信息原样发回。

服务器端

新建一个 UDPSocket 文件夹,进入后,使用命令dotnet new console创建一个新控制台项目,代码如下:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Text;

namespace TCPSocket
{
    class Program
    {
        static void Main(string[] args)
        {   //设置服务器 IP,如果是腾讯云,必须使用内网地址,而不是公网 IP。
            IPAddress ip = IPAddress.Parse("172.16.0.11");
            IPEndPoint point = new IPEndPoint(ip, 5000); //端口指定为 5000
            Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            udpSocket.Bind(point);
            Console.WriteLine("服务器开始侦听...");
            //创建线程接收客户端的消息
            Task.Factory.StartNew(() => ReceiveMessage(udpSocket), TaskCreationOptions.LongRunning);
            Console.ReadLine(); //按回车直接退出程序
        }

        //监听客户端连接的线程方法
        static void ReceiveMessage(Socket udpSocket)
        {
            byte[] buff = new byte[1024]; //创建一个接收缓冲区
            try
            {
                while (true)
                {
                    EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
                    int count = udpSocket.ReceiveFrom(buff, ref remote);
                    //将接收到的数据转化为 ASCII 字符
                    string recvStr = Encoding.ASCII.GetString(buff, 0, count);
                    Console.WriteLine($"接收到来自{remote.ToString()}数据:{recvStr}");
                    udpSocket.SendTo(buff, 0, count, 0, remote);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                udpSocket.Close();
            }
        }
    }
}

本程序实现如下功能:

  1. 由于没有所谓的连接,可以一直的接收 UDP 信息,也就是说,客户端可以多次创建 Socket 向服务器发信息,而服务器不需要重启程序便可接收所有 Socket 的信息。
  2. 当收到消息时,会将消息转化为 ASCII 码字符串打印。
  3. 服务器在收到信息后,原样返回给客户端。
  4. 按回车即可退出程序。

程序运行效果如下图所示,由于和上一个程序类似,我不再详细讲解。

感想

做完两个程序后,还是有一些感想的,我买了两块板,有一块信号不太好,导致调试程序的过程异常痛苦,使用另一块板之后才能确定是信号而不是程序的问题,将来万物互联,NB-IOT 的连接设备数量会非常巨大,在这种情况下,使用 TCP 协议或许并不是最优选择,毕竟 TCP 光建立一个连接就要费不少周折,而且保持连接还会耗费服务器资源和带宽,NB-IOT 的带宽并不优裕。UDP 是更好的选择,来信息直接处理,无需耗费资源保持连接,不占用带宽,可靠性问题可以通过应用层的控制来满足。所以我们也看到,BC26 上的大多数协议也是基于 UDP 进行开发的。这些协议我在后面会一一讲解。

Guess you like

Origin www.cnblogs.com/abatei/p/12117125.html