无需关心数据是否接收完毕,只要有数据发过来,都收到自己的缓冲区当中。
在应用层,打开一个任务以定期扫描缓冲区中的新数据。 如果有新数据,确定其是否为必需的协议帧。 通过帧头帧尾标识符还有校验等判断接收帧的正确性,如果正确再处理,不正确丢弃。
Modbus没有固定的帧头标记,长度也没有固定。 判断时,首先查找具有正确地址的字符,然后找出后续功能代码是否正确。 根据功能代码,确定后续数据有多长并进行校验。 如果验证正确,则说明帧是正确的。
扩展资料:
举例说明如下:
从站地址03,从0开始读取10个寄存器,则接收到的帧为03 03 00 00 00 0a xx xx,查找从站地址03的字节,找到后,以下功能码为03,符合功能码范围。
该功能码的数据包括固定为8个字节的校验和,然后在其后没有8个字节时,表示其已被没收,然后在关闭后进行判断。 如果正确,则可以在应用层中正确处理该帧。
你这种是用的阻塞模式,就是 Accept和Receive 都会卡住不动,直到有新连接或者有新数据。实际使用场景中,阻塞模式,一个线程专门Accept 有新的连接之后,为每一个连接再创建一个线程来处理 Receive,也就是对于服务器来说,假设当前有10个工作的连接,那么至少需要11个线程。
你只需要开几个专门的线程来负责接受连接和接收数据就可以了。
这种阻塞模式不适合大并发量的网络程序,测试小程序没问题,大并发量时需要使用非阻塞模式,比如一般常用的select模式
百度 “select模型” 就可以搜到。
我用的新唐芯片,8051内核,跟51差不多,望采纳void UART_Initial (void)
{
P02_Quasi_Mode //Setting UART pin as Quasi mode for transmit
P16_Quasi_Mode //Setting UART pin as Quasi mode for transmit
SCON_1 = 0x50 //UART1 Mode1,REN_1=1,TI_1=1
T3CON = 0x08 //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1
clr_BRCK
RH3= HIBYTE(65536 - (1000000/u32Baudrate)-1) /*16 MHz */
RL3= LOBYTE(65536 - (1000000/u32Baudrate)-1) /*16 MHz */
set_TR3//Trigger Timer3
}
以上是初始化的
void Send_Data_To_UART1(UINT8 c)
{
TI_1 = 0
SBUF_1 = c
while(TI_1==0)
}
这个是发送
void UART_isr (void) interrupt 4 //串行中断服务程序
{
if (RI_1==1)
{ /* if reception occur */
clr_RI_1/* clear reception flag for next reception */
Receive_Date[c] = SBUF_1
if (Receive_Date[0] == First_Date)
{
c++
}
else if(Receive_Date_Size >0 &&Receive_Date_Size <4)
{
c++
}
else if(Receive_Date[c] == Last_Date &&Receive_Date_Size ==4)
{
c = 0
Flag_Receive_One = 1
}
else
{
c = 0
}
}
}
接收
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)