Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modbus-tcp协议:ERROR Resource temporarily unavailable #724

Open
ssgnh opened this issue Dec 8, 2023 · 1 comment
Open

modbus-tcp协议:ERROR Resource temporarily unavailable #724

ssgnh opened this issue Dec 8, 2023 · 1 comment

Comments

@ssgnh
Copy link

ssgnh commented Dec 8, 2023

您好,我在使用modbus tcp协议写客户端程序,客户端会不停的向服务端发送请求数据。

设置了modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL);

当我将网线拔掉时,调试信息显示 timeout select类似的信息,这是正常的,但是断开网线一段时间后,就会报ERROR Resource temporarily unavailable。调试发现是在执行modbus_read_registers 函数会报此错误。

我在libmodbus源码里调试了下,发现在tcp正常连接中,拔掉网线,程序并没有检测到链路断开(errno)来重新建立连接,而是一直在modbus_flush,然后继续发送,然后就报了Resource temporarily unavailable错误,不知道这样理解是否正确,期待您的回复

  do {
        rc = ctx->backend->send(ctx, msg, msg_length);
        if (rc == -1) {
            _error_print(ctx, NULL);
            if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) {
#ifdef _WIN32
                const int wsa_err = WSAGetLastError();
                if (wsa_err == WSAENETRESET || wsa_err == WSAENOTCONN ||
                    wsa_err == WSAENOTSOCK || wsa_err == WSAESHUTDOWN ||
                    wsa_err == WSAEHOSTUNREACH || wsa_err == WSAECONNABORTED ||
                    wsa_err == WSAECONNRESET || wsa_err == WSAETIMEDOUT) {
                    modbus_close(ctx);
                    _sleep_response_timeout(ctx);
                    modbus_connect(ctx);
                } else {
                    _sleep_response_timeout(ctx);
                    modbus_flush(ctx);
                }
#else
                int saved_errno = errno;

                if ((errno == EBADF || errno == ECONNRESET || errno == EPIPE)) {
                    modbus_close(ctx);
                    _sleep_response_timeout(ctx);
                    modbus_connect(ctx);
                } else {
                    _sleep_response_timeout(ctx);
                    modbus_flush(ctx);
                }
                errno = saved_errno;
#endif
            }
        }
    } while ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) && rc == -1);
@ssgnh
Copy link
Author

ssgnh commented Dec 8, 2023

我又换个例子测试了下,发现,在正常连接成功后,断开网线,‘rc = ctx->backend->send(ctx, msg, msg_length)’返回有值,即使断线了还是正常返回发送字节数,持续了一两分钟后,报Resource temporarily unavailable错误,再过段时间,线程好像就卡住了,或者是死掉了(没写检测线程程序,不知道是不是挂掉了),线程循环里的打印程序就不打印了。查了下,应该是socket 发送缓冲区,应该怎么解决

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant