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

emqx stop后程序退出 #19

Closed
luqinlive opened this issue Oct 27, 2020 · 4 comments
Closed

emqx stop后程序退出 #19

luqinlive opened this issue Oct 27, 2020 · 4 comments

Comments

@luqinlive
Copy link

大神,首先非常感谢这么好的开源项目,我用代码生成器生成了pub和sub函数,断开网线测试重连没有问题,但是把服务手动停止后,客户端直接退出了,有没有方案处理下不直接退出一直去重连,客户端是在hi3559a下编译运行的,谢谢

@jiejieTop
Copy link
Owner

还没有测试过这种情况哦,理论上貌似不会退出吧.

@luqinlive
Copy link
Author

后来发现是emqx退出时发送了清除client命令,mqttclient线程在处理这个命令的时候线程就直接退出了,同理手动剔除这个客户端也会导致退出

@jiejieTop
Copy link
Owner

后来发现是emqx退出时发送了清除client命令,mqttclient线程在处理这个命令的时候线程就直接退出了,同理手动剔除这个客户端也会导致退出

发送了clean肯定会退出吧,如果这都不退出,那岂不是乱套了吗,否则就会导致我手动clean都干不掉这个客户端了

@jiejieTop
Copy link
Owner

对于这个问题,我已经查阅到相关的资料了,不是mqtt本身的问题,而是socket的问题,欢迎联系我交流,微信:1161959934

如果是服务端主动发起关闭,此时四次挥手的顺序会颠倒。那么此时客户端再向服务端发送数据时,根据TCP协议的规定,认为它是一个异常终止连接,客户端将会收到一个RST复位响应(而不是ACK响应),如果客户端再次向服务端发送数据,系统将会发送一个SIGPIPE信号给客户端进程,告诉客户端进程该连接已关闭,不要再写了。系统给SIGPIPE信号的默认处理是直接终止收到该信号的进程,所以此时客户端进程会被极不情愿地终止。
如果不希望客户端进程被终止,可以自定义一个该信号处理的函数,通过调用函数signal(SIGPIPE, handler)实现对信号的处理,其中handler就是可以自定义的函数。
所以说当服务端主动关闭,客户端继续写两次将会导致客户端进程被终止(服务端并不能接收),客户端不能向服务器写入数据。

进程会终止,是因为服务器主动close后,客户端还往服务器写数据。

在你的测试代码里面去添加这些测试代码,你就能捕获到异常情况了:

#include <signal.h>

....


void handler(int h)
{
    printf("signal handler\n");
}

....

int main(void)
{

....

    signal(SIGPIPE, handler);

....

}

....

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

2 participants