memset(packetBuffer,0,255); int len = Udp.read(packetBuffer, 255); packetBuffer[len] = 0;这里为什么要packetBuffer[len] = 0
时间: 2024-05-30 14:10:30 浏览: 130
在这段代码中,我们从UDP接收缓冲区中读取了一定数量的字节,并将它们存储在packetBuffer数组中。但是,我们不知道接收到的数据的确切长度。因此,我们使用len变量来跟踪读取的字节数,并在packetBuffer数组的末尾添加一个空字符('\0'),以确保在我们使用packetBuffer数组时不会出现任何意外问题。
空字符是C语言中的一个特殊字符,用于表示字符串的结尾。它告诉程序在哪里停止读取字符串。如果没有在字符串末尾添加空字符,则程序可能会继续读取内存中的其他数据,导致意外的行为。因此,在处理字符串时,始终要确保在其末尾添加空字符。
相关问题
使用固件库編程:STM32f103+ENC28J60实现PC与开发板udp通信的步骤以及udp.c以及udp.h代码
实现PC与开发板UDP通信的步骤如下:
1. 配置STM32f103的网络接口ENC28J60,配置IP地址和MAC地址等参数;
2. 编写UDP通信的代码,包括UDP的初始化、发送和接收等操作;
3. 在PC端编写UDP通信的代码,包括UDP的初始化、发送和接收等操作;
4. 调试代码,确保能够在PC和STM32f103之间进行UDP通信。
下面是UDP通信的代码示例(udp.c和udp.h):
udp.h
```c
#ifndef __UDP_H__
#define __UDP_H__
#include "stm32f10x.h"
#define UDP_BUFFER_SIZE 1024
void udp_init();
void udp_send(uint8_t *data, uint16_t len);
uint16_t udp_recv(uint8_t *data);
#endif /* __UDP_H__ */
```
udp.c
```c
#include "udp.h"
#include "enc28j60.h"
#include "ip.h"
#include <string.h>
#define UDP_HEADER_SIZE 8
static uint8_t udp_buffer[UDP_BUFFER_SIZE];
static uint16_t udp_data_len = 0;
void udp_init()
{
enc28j60_init();
}
void udp_send(uint8_t *data, uint16_t len)
{
uint16_t udp_len = len + UDP_HEADER_SIZE;
uint16_t ip_len = udp_len + IP_HEADER_SIZE;
uint16_t crc;
// Clear UDP buffer
memset(udp_buffer, 0, UDP_BUFFER_SIZE);
// Set UDP header
udp_buffer[0] = (LOCAL_PORT >> 8) & 0xff;
udp_buffer[1] = LOCAL_PORT & 0xff;
udp_buffer[2] = (REMOTE_PORT >> 8) & 0xff;
udp_buffer[3] = REMOTE_PORT & 0xff;
udp_buffer[4] = (udp_len >> 8) & 0xff;
udp_buffer[5] = udp_len & 0xff;
// Copy data to UDP buffer
memcpy(&udp_buffer[UDP_HEADER_SIZE], data, len);
// Set IP header
ip_init(ip_len);
ip_set_dest_ip(REMOTE_IP);
ip_send();
// Calculate UDP checksum
crc = enc28j60_checksum(&udp_buffer[IP_HEADER_SIZE], udp_len, PROTOCOL_UDP, LOCAL_IP, REMOTE_IP);
udp_buffer[6] = (crc >> 8) & 0xff;
udp_buffer[7] = crc & 0xff;
// Send UDP packet
enc28j60_send_packet(udp_buffer, ip_len);
}
uint16_t udp_recv(uint8_t *data)
{
uint16_t len;
while (1) {
len = enc28j60_recv_packet(udp_buffer, UDP_BUFFER_SIZE);
if (len == 0) {
// No packet received
return 0;
}
if (udp_buffer[IP_PROTOCOL_OFFSET] == PROTOCOL_UDP &&
udp_buffer[UDP_DEST_PORT_OFFSET] == (LOCAL_PORT & 0xff) &&
udp_buffer[UDP_DEST_PORT_OFFSET + 1] == ((LOCAL_PORT >> 8) & 0xff)) {
// Packet is UDP and sent to our port
// Copy data out of UDP buffer
udp_data_len = len - UDP_HEADER_SIZE;
memcpy(data, &udp_buffer[UDP_HEADER_SIZE], udp_data_len);
return udp_data_len;
}
}
}
```
在上面的代码中,我们定义了UDP通信的一些常量和变量,包括本地端口号、远程端口号、本地IP地址、远程IP地址等参数。我们通过udp_init()函数初始化ENC28J60网络接口,并通过udp_send()函数发送UDP数据包,通过udp_recv()函数接收UDP数据包。在发送UDP数据包时,我们首先设置UDP头部,然后把数据拷贝到UDP缓冲区中,接着设置IP头部并发送数据包。在接收UDP数据包时,我们首先使用enc28j60_recv_packet()函数接收数据包,如果接收到的数据包是UDP协议并且发送到本地端口号,就把数据拷贝到指定的缓冲区中。
enum isBOOL{ isFalse=0, isTrue }; enum Choose { TcpHeartbeat=200, TcpExeCmd }; // 定义结构体 struct DataPacket { int sockfd; enum Choose choose; char cmdBuf[BUFFER_SIZE]; char returnValue[BUFFER_SIZE]; }; struct DataPacket datapacket; struct DataPacket receivePackets; int SetUpTCPtoSendInformation(char option[], char **command) { static int isFirstCall = 1; pthread_mutex_lock(&mutex); // 加锁 if (isFirstCall && strstr(option, "set")) { if (TCPCommand != NULL) { free(TCPCommand); } TCPCommand = malloc(strlen(*command) + 1); if (TCPCommand == NULL) { printf("Failed to set and obtain TCP command variable memory allocation\n"); goto fail; } strcpy(TCPCommand, *command); printf("set:%s\n", TCPCommand); isFirstCall = 0; goto succeed; } else if (!isFirstCall && strstr(option, "get") && TCPCommand != NULL && strlen(TCPCommand)) { free(*command); *command = malloc(strlen(TCPCommand) + 1); strcpy(*command, TCPCommand); printf("get:%s\n", *command); memset(TCPCommand, '\0', strlen(TCPCommand)); free(TCPCommand); TCPCommand = NULL; isFirstCall = 1; goto succeed; } memset(*command, 0, sizeof(*command)); strcpy(*command, ""); fail: pthread_mutex_unlock(&mutex); // 解锁 return 0; succeed: pthread_mutex_unlock(&mutex); // 解锁 return 1; } memset(&receivePackets, 0, sizeof(receivePackets)); int dataLen = recv(fd, &receivePackets, sizeof(receivePackets), 0); char *SendString = NULL; int result = SetUpTCPtoSendInformation("get", &SendString); if (result && SendString != NULL && strlen(SendString) > 0)详细代码
根据你提供的代码,我注意到你使用了一个名为 `datapacket` 的结构体来存储发送数据包的信息,并使用 `recv` 函数接收数据包。
在之后的代码中,你调用了 `SetUpTCPtoSendInformation("get", &SendString)` 来获取要发送的字符串。然后,你检查了 `SendString` 是否为 `NULL` 并且长度是否大于零。
这是一个合理的逻辑检查。如果条件满足,你可以使用 `SendString` 的值来执行发送操作。
请注意,你还需要在调用 `recv` 函数之前,使用 `memset` 函数将接收数据包的结构体 `receivePackets` 初始化为零,以确保接收到的数据正确填充到结构体中。
以下是修改后的代码示例:
```c
enum isBOOL {
isFalse = 0,
isTrue
};
enum Choose {
TcpHeartbeat = 200,
TcpExeCmd
};
struct DataPacket {
int sockfd;
enum Choose choose;
char cmdBuf[BUFFER_SIZE];
char returnValue[BUFFER_SIZE];
};
struct DataPacket datapacket;
struct DataPacket receivePackets;
int SetUpTCPtoSendInformation(char option[], char **command) {
static int isFirstCall = 1;
pthread_mutex_lock(&mutex); // 加锁
if (isFirstCall && strstr(option, "set")) {
if (TCPCommand != NULL) {
free(TCPCommand);
}
TCPCommand = malloc(strlen(*command) + 1);
if (TCPCommand == NULL) {
printf("Failed to set and obtain TCP command variable memory allocation\n");
goto fail;
}
strcpy(TCPCommand, *command);
printf("set:%s\n", TCPCommand);
isFirstCall = 0;
goto succeed;
} else if (!isFirstCall && strstr(option, "get") && TCPCommand != NULL && strlen(TCPCommand)) {
free(*command);
*command = malloc(strlen(TCPCommand) + 1);
strcpy(*command, TCPCommand);
printf("get:%s\n", *command);
memset(TCPCommand, '\0', strlen(TCPCommand));
free(TCPCommand);
TCPCommand = NULL;
isFirstCall = 1;
goto succeed;
}
memset(*command, 0, sizeof(*command));
strcpy(*command, "");
fail:
pthread_mutex_unlock(&mutex); // 解锁
return 0;
succeed:
pthread_mutex_unlock(&mutex); // 解锁
return 1;
}
memset(&receivePackets, 0, sizeof(receivePackets)); // 初始化接收数据包的结构体
int dataLen = recv(fd, &receivePackets, sizeof(receivePackets), 0);
char *SendString = NULL;
int result = SetUpTCPtoSendInformation("get", &SendString);
if (result && SendString != NULL && strlen(SendString) > 0) {
// 在这里执行发送 SendString 的操作
printf("SendString: %s\n", SendString);
}
```
请确保你在使用 `SendString` 之前检查其是否为 `NULL`,以避免访问空指针错误。同时,根据你的实际需求,对发送操作进行相应的处理。
阅读全文