为什么我发100个字符却收到104个

本文探讨了使用TCP/IP协议发送消息时遇到的问题:尽管设定的消息长度为100字节,但实际接收到的数据包大小却是104字节。文中询问了这额外的4字节从何而来以及它们的作用。
使用TCP/IP协议
        char *buf = new char[100];
        strcpy(buf,"工作站连接成功。——发往服务器的消息。");
        send(ServerSocket,buf,100,0);
        delete buf;
最长只能是100,而我收到的包中TCP data 总是104 BYTEs,这是为什么呢?是哪个给我加上了最后4个?而且他们的2进制代码都是00 00 00 00,这样加有什么好处?
### 串口通信中送字符串只收到第一个字符的原因及解决方法 在串口通信过程中,送端送完整的字符串,但接收端仅能接收到第一个字符,这种情况通常与送机制、缓冲区管理或中断处理有关。 #### 原因分析 1. **送前未检测串口状态** 在某些嵌入式系统(如STM32)中,如果在串口送前未检测送完成标志(如`TC`标志),可能导致第一个字节被覆盖或未正确送[^1]。例如,在使用`HAL_UART_Transmit`函数前,若串口尚未完成前一次送操作,新的送请求可能会导致数据丢失。 2. **送函数未等待送完成** 某些串口送函数(如`HAL_UART_Transmit_IT`或DMA方式送)采用非阻塞模式,若未等待送完成标志或未正确配置中断回调函数,可能在数据尚未完全送时就退出送函数,导致后续字符未被送[^1]。 3. **接收端未正确清空中断标志** 在接收端,若未在中断服务函数中正确清除接收中断标志(如`RI`),则可能只触一次中断,导致只能接收到第一个字符[^2]。例如,在51单片机中,若未在中断处理中手动清除`RI`标志,则后续数据将无法被接收。 4. **缓冲区未及时读取或覆盖** 若接收端采用轮询方式读取数据但未及时处理接收缓冲区,可能导致新数据覆盖旧数据,使得每次只能读取到最新的字符。 #### 解决方法 1. **送前检测串口状态** 在调用送函数前,应检测串口是否处于空闲状态。例如,在STM32 HAL库中,可以使用如下方式确保送完成后再送新数据: ```c while (huart1.gState != HAL_UART_STATE_READY); // 等待串口空闲 HAL_UART_Transmit(&huart1, (uint8_t*)"Hello", 5, HAL_MAX_DELAY); ``` 2. **使用阻塞式送函数** 若不需要实时性要求,建议使用阻塞式送函数(如`HAL_UART_Transmit`),该函数会等待送完成后再返回,避免因未等待送完成而导致的数据丢失。 3. **在中断处理中清除接收标志** 接收端应确保在每次接收到数据后及时清除接收中断标志。例如,在51单片机中,应在中断服务函数中清除`RI`标志: ```c void UART_ISR(void) interrupt 4 { if (RI) { RI = 0; // 清除接收中断标志 buffer[rx_index++] = SBUF; } } ``` 4. **使用环形缓冲区管理接收数据** 接收端应使用环形缓冲区(Ring Buffer)来管理接收数据,避免因缓冲区覆盖导致数据丢失。例如,可以使用如下结构体管理接收缓冲区: ```c #define RX_BUFFER_SIZE 128 uint8_t rx_buffer[RX_BUFFER_SIZE]; uint16_t rx_head = 0; uint16_t rx_tail = 0; void UART_Receive_Handler(uint8_t data) { uint16_t next = (rx_head + 1) % RX_BUFFER_SIZE; if (next != rx_tail) { rx_buffer[rx_head] = data; rx_head = next; } } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值