实验环境:

1.  虚拟机:VirtualBox6.0

2.  Ubuntu系统: ubuntu-20.04.1-desktop-amd64

3.  ESP8266: NodeMCU开发板

4.  SDK:V3.4

5.  使用乐鑫SDK提供examples实验使用

 

@0、补充:编译完成后下载出现ttyUSB0找不到的问题:

(图0.00找不到ttyUSB0)

esp8266 SDK json 各函数的作用 esp8266 socket_socket

这样需要设置好虚拟机和Ubuntu,然后插拔USB重新挂载:

(图0.10Ubuntu设置USB)

esp8266 SDK json 各函数的作用 esp8266 socket_网络_02

(图0.11拔插USB显示连接上USB)

esp8266 SDK json 各函数的作用 esp8266 socket_http_03

最后使用命令使Ubuntu挂载USB0:

1.sudo usermod -a -G dialout $USER

2.sudo chmod -R 777 /dev/ttyUSB0

(图0.12可以正常下载和窗口监视)

esp8266 SDK json 各函数的作用 esp8266 socket_网络_04

 

=================================== 分割线 ====================================

@1、Socket预备知识:

 

(图1.00Socket在网络中的结构)

@2、TcpServer和 TcpClient

(图2.00TCP协议结构流程图)

esp8266 SDK json 各函数的作用 esp8266 socket_socket_05

TcpServer和 TcpClient流程基本相同,不过TcpServer相对来说多了些流程。复制到工作目录下边。

(图2.10复制Tcp_Server文件到实验目录)

esp8266 SDK json 各函数的作用 esp8266 socket_c语言_06

打开Tcp_Server.c文件修改app_main为TcpServer_init,使用CONFIG_EXAMPLE_IPV4而非IPV6。

(图2.11修改app_main方便调用)

esp8266 SDK json 各函数的作用 esp8266 socket_网络_07

(图2.11修改app_main方便调用1)

esp8266 SDK json 各函数的作用 esp8266 socket_网络_08

(图2.12设置端口且使用IPV4)

esp8266 SDK json 各函数的作用 esp8266 socket_c语言_09

在app_main函数中调用TcpServer_init完成TcpServer功能

(图2.13调用TcpServer功能)

esp8266 SDK json 各函数的作用 esp8266 socket_嵌入式_10

下载即可使用

@2、tcpclient功能设置与tcpserver基本相同!

@3、udpclient功能设置和udpserver操作也基本相同!!!

for(;;)
	{
		//使用IPV4
    struct sockaddr_in destAddr;	//处理网络通信地址的结构体(服务器)
    destAddr.sin_addr.s_addr = htonl(INADDR_ANY);	//把本机字节顺序转化为网络字节顺序
    destAddr.sin_family = AF_INET;		//domain:(TCP/IP – IPv4)
    destAddr.sin_port = htons(PORT);		//将主机字节顺序转换为网络字节顺序
    addr_family = AF_INET;		//domain:(TCP/IP – IPv4)
    ip_protocol = IPPROTO_IP;	//#define IPPROTO_IP 0 /* dummy for IP */
    
    inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);	//转换IP地址到ASIIC字符串的函数
//===================================================================		
    int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol);	//返回状态码
   
   //ESP_LOGI == printf
    if (listen_sock < 0) {		//返回-1表示失败,其他值参考:
        ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
        break;
    }
    ESP_LOGI(TAG, "Socket created");		//返回正常值说明Socket已经建立起来了
    
    int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));	//把一个本地协议地址赋予一个套接字
    //返回值表示绑定操作是否成功,0表示成功, -1表示不成功。函数的返回值千万不要忽视,上次就被人说了。
    if (err != 0) {
        ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
        break;
    }
    ESP_LOGI(TAG, "Socket binded");

    err = listen(listen_sock, 1);		//设置监听和队列数
    if (err != 0) {
        ESP_LOGE(TAG, "Error occured during listen: errno %d", errno);
        break;
    }
    ESP_LOGI(TAG, "Socket listening");	//成功监听
//===================================================================		
    //使用IPV4
    struct sockaddr_in sourceAddr;	//处理网络通信地址的结构体(客户端)
    
    uint addrLen = sizeof(sourceAddr);	//地址大小
    int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
    if (sock < 0) {
        ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
        break;
    }
    ESP_LOGI(TAG, "Socket accepted");  	//阻塞处理-进行握手连接  
//===================================================================		
    
    while (1) //处于监听状态
    {
    	int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);	//从TCP连接的另一端接收数据
    	// Error occured during receiving
    	if (len < 0){	//recv在copy时出错了
        ESP_LOGE(TAG, "recv failed: errno %d", errno);
        break;
    	}
    	// Connection closed
    	else if (len == 0) {	//等待协议接收数据时网络中断了
        ESP_LOGI(TAG, "Connection closed");
        break;
   		}
    // Data received
    	else {	//返回值>0,接收实际copy字节数
       	inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
       	
       	rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
       	ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str);
       	ESP_LOGI(TAG, "%s", rx_buffer);

       	int err = send(sock, rx_buffer, len, 0);	//发送回所接收到的数据
       	if (err < 0) {
           ESP_LOGE(TAG, "Error occured during sending: errno %d", errno);
           break;
       	}
     	}
    }
    
    if (sock != -1) {
        ESP_LOGE(TAG, "Shutting down socket and restarting...");
        shutdown(sock, 0);
        close(sock);
    }
	}

技术总结:

@一、注意USB0的挂载问题!

@二、要复制components文件到实验目录,否则会找不到protocol_examples_common.h头文件!

(图3.13网络连接头文件)

esp8266 SDK json 各函数的作用 esp8266 socket_嵌入式_11