TCP模式客户端在不超时情况下进行第二包数据请求时提示服务器关闭
我在用libmodbus在单片机上实现ModbusTCP,发现客户端连接上进行一次F03输入寄存器读取后,再次进行数据获取时提示服务器关闭,此时也没超时。请问libmodbus是不是就是涉及的每进行一次数据交互就对连接的客户端关闭一次?客户端处理完后会选择关闭连接,在不超时情况下怎么让服务器不关闭已经通讯一次的客户端连接?
无论是使用哪个modbusTCP工具,都是连续读取没问题,但是客户端断开后再连接就读取就不行了,我使用的是libmodbus在rt-thread的实现,地址https://github.com/settings/emails;同时我把这个主要相关的线程相关的函数以附件提供,希望大家帮我想想办法,或者用[email protected]与我沟通交流`#include "modbus_tcp_test.h" #include <modbus.h> #include <stdio.h> #include <string.h> #include <dfs_posix.h> #include <sys/time.h> #include <dfs_select.h> #include <sal_socket.h>
#define MAX_CLIENT_NUM 2 #define CLIENT_TIMEOUT 5 //单位 s
typedef struct { int fd; rt_tick_t tick_timeout; }client_session_t;
static void mbtcp_thread(void *param) { int server_fd = -1; modbus_t *ctx = NULL; modbus_mapping_t *mb_mapping = NULL; client_session_t client_session[MAX_CLIENT_NUM];
for (int i = 0; i < MAX_CLIENT_NUM; i++)
{
client_session[i].fd = -1;
client_session[i].tick_timeout = rt_tick_get() + rt_tick_from_millisecond(CLIENT_TIMEOUT * 1000);
}
int max_fd = -1;
fd_set readset;
int rc;
struct timeval select_timeout;
select_timeout.tv_sec = 1;
select_timeout.tv_usec = 0;
//ctx = modbus_new_tcp(RT_NULL, 1502, AF_INET);
ctx = modbus_new_tcp("192.168.1.250", 502, AF_WIZ);
RT_ASSERT(ctx != RT_NULL);
/*mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS, 0,
MODBUS_MAX_READ_REGISTERS, 0);*/
mb_mapping =modbus_mapping_new_start_address(0, MODBUS_MAX_NB_BITS, 10000, MODBUS_MAX_NB_INPUT_BITS, 40000, MODBUS_MAX_WRITE_REGISTERS, 30000, MODBUS_MAX_READ_REGISTERS);
for(rt_uint8_t i=0;i<MODBUS_MAX_READ_REGISTERS;i++)
{
mb_mapping->tab_input_registers[i]=i;
}
RT_ASSERT(mb_mapping != RT_NULL);
_mbtcp_start: server_fd = modbus_tcp_listen(ctx, 1); if (server_fd < 0) goto _mbtcp_restart;
while (1)
{
max_fd = -1;
FD_ZERO(&readset);
FD_SET(server_fd, &readset);
if(max_fd < server_fd)
max_fd = server_fd;
for (int i = 0; i < MAX_CLIENT_NUM; i++)
{
if(client_session[i].fd >= 0)
{
FD_SET(client_session[i].fd, &readset);
if(max_fd < client_session[i].fd)
max_fd = client_session[i].fd;
}
}
rc = select(max_fd + 1, &readset, RT_NULL, RT_NULL, &select_timeout);
if(rc < 0)
{
goto _mbtcp_restart;
}
else if(rc > 0)
{
if(FD_ISSET(server_fd, &readset))
{
int client_sock_fd = modbus_tcp_accept(ctx, &server_fd);
if(client_sock_fd >= 0)
{
int index = -1;
for (int i = 0; i < MAX_CLIENT_NUM; i++)
{
if(client_session[i].fd < 0)
{
index = i;
break;
}
}
if(index >= 0)
{
client_session[index].fd = client_sock_fd;
client_session[index].tick_timeout = rt_tick_get() + rt_tick_from_millisecond(CLIENT_TIMEOUT * 1000);
}
else
{
close(client_sock_fd);
}
}
}
for (int i = 0; i < MAX_CLIENT_NUM; i++)
{
if(client_session[i].fd >= 0)
{
if(FD_ISSET(client_session[i].fd, &readset))
{
uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
modbus_set_socket(ctx, client_session[i].fd);
rc = modbus_receive(ctx, query);
if (rc > 0)
{
rc = modbus_reply(ctx, query, rc, mb_mapping);
if(rc < 0)
{
close(client_session[i].fd);
client_session[i].fd = -1;
}
else
{
client_session[i].tick_timeout = rt_tick_get() + rt_tick_from_millisecond(CLIENT_TIMEOUT * 1000);
}
}
else
{
close(client_session[i].fd);
client_session[i].fd = -1;
}
}
}
}
}
// 客户端超时未收到数据断开
for(int i =0;i<MAX_CLIENT_NUM;i++)
{
if(client_session[i].fd >= 0)
{
//超时
if((rt_tick_get() - client_session[i].tick_timeout) < (RT_TICK_MAX / 2))
{
close(client_session[i].fd);
client_session[i].fd = -1;
}
}
}
}
_mbtcp_restart: if(server_fd >= 0) { close(server_fd); server_fd = -1; }
for(int i =0;i<MAX_CLIENT_NUM;i++)
{
if(client_session[i].fd >= 0)
{
close(client_session[i].fd);
client_session[i].fd = -1;
}
}
rt_thread_mdelay(5000);
goto _mbtcp_start;
modbus_free(ctx);
}
static int tcp_test_init(void) { rt_thread_t tid_mbtcp; tid_mbtcp = rt_thread_create("mbtcp_test", mbtcp_thread, RT_NULL, 4096, 5, 10); if (tid_mbtcp != RT_NULL) rt_thread_startup(tid_mbtcp); return RT_EOK; } INIT_APP_EXPORT(tcp_test_init); `
上一个问题增大Listen监听的数目可以改善,但不能根除; 现在新的问题: 1 我低层的网卡用的时W5500硬件协议栈,如果中间通过modbusTCP修改连接IP后,释放tx资源重新建立服务器,但时低端的W5500如果不初始化就会出现W5500的IP因为和新IP不一样服务器创建失败。如果W5500初始化,并且要在TCP之前初始化,又会出现一些其它错误。libmodbus在动态修改IP这方面有什么处理的技巧? 2 对于libmodbusTCP,在reply时将一些功能码合并,比如读线圈或者离散量,或者读输入寄存器和保持寄存器,在判断读写数目时用的宏变量if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) 或者if (nb < 1 || MODBUS_MAX_READ_BITS < nb) 这里是不是给nb_registers和nb_bits才正确,还是说除了我们常规理解的以下4个宏之外 MODBUS_MAX_NB_BITS 表示coil MODBUS_MAX_NB_INPUT_BITS 表示desc MODBUS_MAX_READ_REGISTERS 表示input-reg MODBUS_MAX_WRITE_REGISTERS 表示hold-reg
后面的这4个个宏是希望怎么使用的? #define MODBUS_MAX_READ_BITS 6 //2000 #define MODBUS_MAX_WRITE_BITS 53 //1968 #define MODBUS_MAX_WR_WRITE_REGISTERS 0 //121 #define MODBUS_MAX_WR_READ_REGISTERS 0 //125
Are you aware that most of this message is in an Asian script? Most people in this group can’t read the message and therefore can’t assist?
If this was your intention, no problem.
From: zhigangbox [email protected] Sent: Wednesday, June 10, 2020 6:13 AM To: stephane/libmodbus [email protected] Cc: Subscribed [email protected] Subject: Re: [stephane/libmodbus] TCP模式客户端在不超时情况下进行第二包数据请求时提示服务器关闭 (#543)
上一个问题增大Listen监听的数目可以改善,但不能根除; 现在新的问题: 1 我低层的网卡用的时W5500硬件协议栈,如果中间通过modbusTCP修改连接IP后,释放tx资源重新建立服务器,但时低端的W5500如果不初始化就会出现W5500的IP因为和新IP不一样服务器创建失败。如果W5500初始化,并且要在TCP之前初始化,又会出现一些其它错误。libmodbus在动态修改IP这方面有什么处理的技巧? 2 对于libmodbusTCP,在reply时将一些功能码合并,比如读线圈或者离散量,或者读输入寄存器和保持寄存器,在判断读写数目时用的宏变量if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) 或者if (nb < 1 || MODBUS_MAX_READ_BITS < nb) 这里是不是给nb_registers和nb_bits才正确,还是说除了我们常规理解的以下4个宏之外 MODBUS_MAX_NB_BITS 表示coil MODBUS_MAX_NB_INPUT_BITS 表示desc MODBUS_MAX_READ_REGISTERS 表示input-reg MODBUS_MAX_WRITE_REGISTERS 表示hold-reg
后面的这4个个宏是希望怎么使用的? #define MODBUS_MAX_READ_BITS 6 //2000 #define MODBUS_MAX_WRITE_BITS 53 //1968 #define MODBUS_MAX_WR_WRITE_REGISTERS 0 //121 #define MODBUS_MAX_WR_READ_REGISTERS 0 //125
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/stephane/libmodbus/issues/543#issuecomment-641902896 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFDSANJQRCDDLVKXXMM2KDRV5MDHANCNFSM4NSRWCKA . https://github.com/notifications/beacon/AAFDSANEG27FGD52QVMJHBDRV5MDHA5CNFSM4NSRWCKKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEZBKSMA.gif