4.物联网LWIP之C/S编程,实现服务器大小写转换

这篇具有很好参考价值的文章主要介绍了4.物联网LWIP之C/S编程,实现服务器大小写转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

LWIP配置

服务器端实现

客户端实现

错误分析

一。LWIP配置(FREERTOS配置,ETH配置,LWIP配置)

1.FREERTOS配置

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 为什么要修改定时源为Tim1?不用systick?

原因:HAL库与FREERTOS都需要使用systick,两者冲突,所以修改时钟源,让FREERTOS使用Tim1。

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 2.ETH配置

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 3.LWIP配置

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

不使用DHCP

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 4.步骤:
(1)freertos.c中会自己出现一个Lwip初始化

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

运行后结果:命令行中输入ping 192.168.1.10有回复

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 二。服务器端

实验一:《stm32作为服务器端,COMMBOX串口作为客户端》

1.功能分析

小写转大写

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 2.步骤:

(1)建立socket_tcp_server.h

#ifndef SOCKET_TCP_SERVER_H
#define SOCKET_TCP_SERVER_H

#define SERVER_IP				"192.168.1.11"
#define SERVER_PORT			6666
#define BUFF_SIZE				1024

void vTcpServerTask(void);

#endif

 (2)建立socket_tcp_server.c,并添加到文件中

#include "socket_tcp_server.h"
#include "lwip/sockets.h"
#include "ctype.h"

char ReadBuff[BUFF_SIZE];

/**
  * @brief  TCP 服务器任务
  * @param  None
  * @retval None
  */
void vTcpServerTask(void){

	int 	 sfd, cfd, n, i;
	struct sockaddr_in server_addr, client_addr;
	socklen_t	client_addr_len;
	
	//创建socket
	sfd = socket(AF_INET, SOCK_STREAM, 0);
	server_addr.sin_family 			= AF_INET;
	server_addr.sin_port   			= htons(SERVER_PORT);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	//绑定socket
	bind(sfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
	//监听socket
	listen(sfd, 5);
	//等待客户端连接
	client_addr_len = sizeof(client_addr);
	cfd = accept(sfd, (struct sockaddr *)&client_addr, &client_addr_len);
	printf("client is connect cfd = %d\r\n",cfd);
	while(1){
		//等待客户端发送数据
		n = read(cfd, ReadBuff, BUFF_SIZE);
		//进行大小写转换
		for(i = 0; i < n; i++){
		
			ReadBuff[i] = toupper(ReadBuff[i]);		
		}
		//写回客户端
		write(cfd, ReadBuff, n);
	}
}

(3)freertos.c中网络任务中,添加服务器运行函数。

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 不要忘记添加头文件

	vTcpServerTask();	

3.现象演示

(1)使用COMMBOX串口调试工程,添加socket网络客户端 ,目标ip为stm32的ip.端口在.h中

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

(2)stm32客户端发送的字母变大写

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言 三。客户端创建

实验二:《stm32作为客户端,COMMBOX串口作为服务器端》

1.创建socket_tcp_client.c与socket_tcp_client.h

(1)socket_tcp_client.c

#include "socket_tcp_server.h"
#include "socket_tcp_client.h"
#include "lwip/sockets.h"
#include "ctype.h"

static char ReadBuff[BUFF_SIZE];


void vTcpClientTask(void)
{

	int 	 cfd, n, i;
	struct sockaddr_in server_addr;
	
	//创建socket
	cfd = socket(AF_INET, SOCK_STREAM, 0);
	
	server_addr.sin_family 			= AF_INET;
	server_addr.sin_port   			= htons(SERVER_PORT);
	server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
	//连接到服务器
	connect(cfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
	printf("server is connect ok\r\n");
	
	while(1){
		//等待服务器发送数据
		n = read(cfd, ReadBuff, BUFF_SIZE);
		//进行大小写转换
		for(i = 0; i < n; i++){
		
			ReadBuff[i] = toupper(ReadBuff[i]);		
		}
		//写回服务器
		write(cfd, ReadBuff, n);
	}
}

(2)socket_tcp_client.h

#ifndef _SOCKET_TCP_CLIENT_H
#define _SOCKET_TCP_CLIENT_H

void vTcpClientTask(void);

#endif

可能遇到的问题:

        由于打开了防火墙,所以无法连接

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 补充:上述代码的问题

        1.代码封装性不好

        2.代码对边界错误提示太少

四。代码的优化

1.函数在封装,文件为socket_warp.c与socket_warp.h

(1)socket_warp.h

#ifndef _SOCKET_WRAP_H
#define _SOCKET_WRAP_H

#include "lwip/sockets.h"

int Socket(int domain, int type, int protocol);

int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

int Listen(int sockfd, int backlog);

int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

int Write(int fd,const void *buf,size_t nbytes);
int Read(int fd,void *buf,size_t nbyte);

int Sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
int Recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, socklen_t *fromlen);

#endif

(2)socket_warp.c

#include "socket_wrap.h"
#include "FreeRTOS.h"
#include "task.h"

int Socket(int domain, int type, int protocol){
	int fd;
	fd=socket(domain,type,protocol);
	if(fd<0){
		printf("create socket error\n");
		//没有创建完成,那么这个任务也没有必要运行,直接切换上下文
		//返回一个小于零的数
		vTaskDelete(NULL);
	}
	return fd;
}

int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
	int ret;
	ret=bind(sockfd,addr,addrlen);
	if(ret < 0){
		printf("bind socket error\r\n");
		//当调用删除任务,就会切换上下文,CPU执行其他任务
		vTaskDelete(NULL);		
	}
	return ret;
}

int Listen(int sockfd, int backlog){
	int ret;
	ret=listen(sockfd,backlog);
	if(ret<0){
		printf("listen socket error\n");
		vTaskDelete(NULL);
	}
	return ret;
}

int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen){
	int fd;
again:	
	fd=accept(sockfd,addr,addrlen);
	if(fd<0){
		printf("accept socket error\n");
		goto again;
	}
	return fd;
}
int Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
	int ret;
	ret=connect(sockfd,addr,addrlen);
	if(ret<0){
		printf("connect socket error\n");
		//先关闭当前的socket,其实内部是删除这个socket的内存块,不删除会导致下次无法生成
		close(sockfd);
	}
	return ret;
}

int Write(int fd,const void *buf,size_t nbytes){
	int ret;
	ret=write(fd,buf,nbytes);
	//没有书写完成就关闭socket
	if(ret<0){
		printf("write socket error\n");
		close(fd);
	}
	return ret;
}
int Read(int fd,void *buf,size_t nbyte){
	int ret;
	ret=read(fd,buf,nbyte);
	if(ret==0){
		printf("read socket is close\n");
		close(fd);
	}else if(ret<0){
		printf("read socket error\n");
		close(fd);
	}
}

int Sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen){
	int ret;
again:	
	ret=sendto(sockfd,msg,len,flags,to,tolen);
	if(ret<0){
		printf("sendto socket error\n");
		goto again;
	}
	return ret;
}


int Recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, socklen_t *fromlen){
	int ret;
again:	
	ret=recvfrom(sockfd,buf,len,flags,from,fromlen);
	if(ret<0){
		printf("recvfrom socket error\n");
		goto again;				
	}
	return ret;
}

上述为封装函数,包括tcp_server,tcp_client已经后续的udp_server

2.socket_tcp_server.c与socket_tcp_client.c

1.socket_tcp_server.c

#include "socket_udp_server.h"
#include "socket_tcp_server.h"
#include "socket_wrap.h"
#include "ctype.h"

static char ReadBuff[BUFF_SIZE];


void vUdpServerTask(){
	
	int 	 sfd, n, i;
	struct sockaddr_in server_addr, client_addr;
	socklen_t	client_addr_len;
	int optval=1;
	
	//创建socket
	sfd=Socket(AF_INET, SOCK_DGRAM, 0);
	setsockopt(sfd,SOL_SOCKET ,SO_BROADCAST,&optval,sizeof(optval));
	
	//绑定socket
	server_addr.sin_family 			= AF_INET;
	server_addr.sin_port   			= htons(SERVER_PORT);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	Bind(sfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
	
	//处理
	client_addr_len=sizeof(client_addr);
	while(1){
		//等待客户端发送数据
		n = Recvfrom(sfd, ReadBuff, BUFF_SIZE, 0, (struct sockaddr *)&client_addr, &client_addr_len);
		ReadBuff[n] = '\0';
		printf("recv data:%s\r\n",ReadBuff);
		//进行大小写转换
		for(i = 0; i < n; i++){	
			ReadBuff[i] = toupper(ReadBuff[i]);		
		}
		//写回客户端
		Sendto(sfd, ReadBuff, n, 0, (struct sockaddr *)&client_addr, client_addr_len);
		
	}
	
}

2.socket_tcp_client.c

#include "socket_tcp_server.h"
#include "socket_tcp_client.h"
#include "socket_wrap.h"
#include "ctype.h"
#include "FreeRTOS.h"
#include "task.h"

#include "string.h"

static char ReadBuff[BUFF_SIZE];


void vTcpClientTask(void)
{

	int 	 cfd, n, i, ret;
	struct sockaddr_in server_addr;
	
//	int so_reuseaddr_val = 1;
again:
	//创建socket
	cfd = Socket(AF_UNSPEC, SOCK_STREAM, 0);
	
//使能socket层 心跳检测
//	setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr_val, sizeof(int));
	
	server_addr.sin_family 			= AF_INET;
	server_addr.sin_port   			= htons(SERVER_PORT);
	server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);	
	//连接到服务器
	//connect 其实是一个阻塞接口,内部要完成TCP的三次握手,当然有超时机制,所以我们需要等一段时间,才能重新连接到服务器
	ret = connect(cfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
	if(ret < 0){
		//100ms去连接一次服务器
		vTaskDelay(1000);
		printf("connect fail\r\n");
		goto again;
	
	}
	
	printf("server is connect ok\r\n");
	
	while(1){
		//等待服务器发送数据
		n = Read(cfd, ReadBuff, BUFF_SIZE);
		if(n <= 0){
		
			goto again;
		
		}
		//进行大小写转换
		for(i = 0; i < n; i++){
		
			ReadBuff[i] = toupper(ReadBuff[i]);		
		}
		//写回服务器
		n = Write(cfd, ReadBuff, n);
		if(n <= 0){
		
			goto again;
		
		}
		
	}
}

结果:pc端的COMMBOX创建或者关闭服务器或者客户端时,串口都会打印出内容,提示打开或者关闭。

补充:

1.当stm32作为服务器端时:
4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

2.当stm32作为客户端时:

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 所以我们本机配置也应该为:192.168.1.11

(1) stm32开始运行后,wifi中会出现一个未识别网络,点击他。

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

(2)点击更改适配器选项

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

 (3)配置:右键--》属性4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

(4)配置IPv4

 4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

(5)电脑配置:自己的IP地址为192.168.1.11(当然127.0.0.1也可以,表示自己)

4.物联网LWIP之C/S编程,实现服务器大小写转换,物联网,c语言,开发语言

综上:

(1)stm32的ip在cubemx上创建

(2)电脑的IP在网络的适配器上设置文章来源地址https://www.toymoban.com/news/detail-664698.html

到了这里,关于4.物联网LWIP之C/S编程,实现服务器大小写转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity进阶--通过PhotonServer实现联网登录注册功能(服务器端)--PhotonServer(二)

    如何配置PhotonServer服务器:https://blog.csdn.net/abaidaye/article/details/132096415 大体结构图 结构图示意 BLL层(控制层) 总管理类 控制层接口 登录注册控制类 DAL层(数据控制层) 总数据管理层 登录注册数据管理层 模型层 登录注册层 DLC 服务器配置类 发送消息类 以及消息类 服务器

    2024年02月14日
    浏览(42)
  • lwip-2.1.3自带的httpd网页服务器使用教程(二)使用SSI动态生成网页部分内容

    上一篇:lwip-2.1.3自带的httpd网页服务器使用教程(一)从SD卡读取网页文件并显示 (本节例程名称:ssi_test) 电脑上用的Web服务器采用ASP、PHP或JSP动态网页技术后,可以根据HTTP模板(asp、php或jsp文件),动态替换掉网页中的% %或?php ?标签,生成动态网页。lwip自带的httpd也有类

    2024年02月10日
    浏览(35)
  • 网络编程: 服务器百万连接实现

    实验内容: 用三个客户端与服务器建立百万连接 服务器代码: Reactor 将实验遇到的问题记录如下 一个TCP连接叫做TCP控制块(tcp control block)。区分网络连接的五元组元素有 添加功能 增加服务器监听端口 如果服务器只用一个端口,那么至少需要10e6/(2^16-1024) ≈ 16台虚拟机。(能分

    2024年01月20日
    浏览(47)
  • lwip-2.1.3自带的httpd网页服务器使用教程(一)从SD卡读取网页文件并显示

    本教程使用的单片机是STM32F103ZE,有线网口芯片为ENC28J60。 本教程里面的网页由于需要兼容Windows XP系统的IE8浏览器,所以采用HTML 4.01编写,不使用任何前端框架。笔者使用的网页设计软件是Adobe Dreamweaver CS3。 开发板PCB文件是公开的,大家可以拿去打印出来,焊好器件后,就可

    2024年02月15日
    浏览(34)
  • 【socket编程】TCP服务器、UDP服务器、本地套接字【C语言代码实现】

    目录 0. 准备知识 0.1 大小端概念 0.2 网络字节序和主机字节序的转换 0.3 点分十进制串转换(IP地址转换函数) 0.4 IPV4结构体:(man 7 ip) 0.5 IPV6套接字结构体:(man 7 ipv6) 0.6 通用套接字结构体 1. 网络套接字函数 1.1 socket 1.2 connect 1.3 bind 1.4 listen 1.5 accept 1.6 端口复用 2. 包裹函

    2024年02月07日
    浏览(50)
  • 【网络编程】demo版TCP网络服务器实现

    UDP和TCP的区别: 对于TCP协议有几个特点: 1️⃣ 传输层协议 2️⃣ 有连接(正式通信前要先建立连接) 3️⃣ 可靠传输(在内部帮我们做可靠传输工作) 4️⃣ 面向字节流 对于UDP协议有几个特点: 1️⃣ 传输层协议 2️⃣ 无连接 3️⃣ 不可靠传输 4️⃣ 面向数据报 可以看到

    2024年02月06日
    浏览(51)
  • 【网络编程】demo版UDP网络服务器实现

    在上一章【网络编程】socket套接字中我们讲述了TCP/UDP协议,这一篇就是简单实现一个UDP协议的网络服务器。 我们也讲过其实 网络通信的本质就是进程间通信 。而进程间通信无非就是读和写(IO)。 所以现在我们就要写一个服务端(server)接收数据,客户端(client)发送数据

    2024年02月02日
    浏览(44)
  • Java 网络编程 —— 实现非阻塞式的服务器

    当 ServerSocketChannel 与 SockelChannel 采用默认的阻塞模式时,为了同时处理多个客户的连接,必须使用多线程 在非阻塞模式下, EchoServer 只需要启动一个主线程,就能同时处理三件事: 接收客户的连接 接收客户发送的数据 向客户发回响应数据 EchoServer 委托 Selector 来负责监控接

    2024年02月05日
    浏览(54)
  • 【网络编程】实现UDP/TCP客户端、服务器

    需要云服务器等云产品来学习Linux的同学可以移步/--腾讯云--/--阿里云--/--华为云--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。   目录 一、UDP 1、Linux客户端、服务器 1.1udpServer.hpp 1.2udpServer.cc 1.3udpClient.hpp 1.4udpClient.cc 1.5onlineUser.hpp 2、Windows客户端 二、T

    2024年02月06日
    浏览(58)
  • 【网络编程】TCP流套接字编程(TCP实现回显服务器)

    Socket(既能给客户端使用,也能给服务器使用) 构造方法 基本方法: ServerSocket(只能给服务器使用) 构造方法: 基本方法: 客户端代码示例: 服务器代码示例: 运行结果: 代码执行流程: 服务器启动,阻塞在accept,等待客户端建立连接. 客户端启动.这里的new操作会触发和服务器之间建立连

    2024年04月25日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包