关闭插座的最佳做法. SO_LINGER还是关闭/关闭? [英] Best practice for closing sockets. SO_LINGER or shutdown/close?

查看:149
本文介绍了关闭插座的最佳做法. SO_LINGER还是关闭/关闭?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

那里有很多混合信息.

我只想确保数据已完全发送.我应该关闭/关闭还是使用SO_LINGER和超时关闭?

I just want to ensure that the data is fully sent. Should I be doing shutdown/close or close with SO_LINGER and timeout ?

我在Linux下使用epoll的非阻塞套接字,而在OSX下使用queue的相同代码(带有define).看来SO_LINGER并非在所有平台上都总是一样工作吗?

I'm using non-blocking sockets with epoll under Linux and the same code (with defines) under OSX uses kqueue. It would seem SO_LINGER doesn't always work the same on all platforms?

另外,在非阻塞套接字上使用SO_LINGER时,如果返回EWOULDBLOCK,是否需要再次调用close,直到没有得到EWOULDBLOCK?还是在这种情况下我只能从关闭忽略EWOULDBLOCK错误?

Also when using SO_LINGER on a non-blocking socket, If you get back EWOULDBLOCK do you need to call close again until you don't get EWOULDBLOCK? or can I just ignore the EWOULDBLOCK error from close in that case?

推荐答案

我只想确保数据已完全发送.我应该关闭/关闭吗

I just want to ensure that the data is fully sent. Should I be doing shutdown/close

是,请参见下文.

还是关闭SO_LINGER并超时?

or close with SO_LINGER and timeout?

我认为这根本没有用,请参阅下文.

I don't find this at all useful, see below.

我在Linux下使用epoll的非阻塞套接字,而在OSX下使用queue的相同代码(带有define).看来SO_LINGER并非在所有平台上都总是一样工作吗?

I'm using non-blocking sockets with epoll under Linux and the same code (with defines) under OSX uses kqueue. It would seem SO_LINGER doesn't always work the same on all platforms?

应该,但是谁知道呢?关于TCP实现的差异,有大量论文,据我所知,其中没有提到SO_LINGER.但是我会稍后检查.

It should but who knows? There is a large paper on TCP implementation differences, and SO_LINGER isn't mentioned in it as far as I remember. But I'll check later when I can.

另外,在非阻塞套接字上使用SO_LINGER时,如果返回EWOULDBLOCK,是否需要再次调用close,直到没有得到EWOULDBLOCK?还是在这种情况下我只能从关闭忽略EWOULDBLOCK错误?

Also when using SO_LINGER on a non-blocking socket, If you get back EWOULDBLOCK do you need to call close again until you don't get EWOULDBLOCK? or can I just ignore the EWOULDBLOCK error from close in that case?

理论上,您应该遵从EAGAIN再次调用close(),但是我想知道它是否真的有效.将套接字置于阻塞模式以使其关闭更有意义,因为您无法选择的任何内容将告诉您何时已写入所有数据.但是,您仍然有一个问题,如果发生超时,套接字将关闭,数据可能会丢失,并且现在除了记录问题的可能性之外,您无能为力.

Theoretically you should call close() again in obedience to EAGAIN but I'm wondering whether it would actually work. It would make more sense to put the socket into blocking mode for the close, as there is nothing you can select on that will tell you when all the data has been written. But you still have the problem that if the timeout occurs, the socket is closed, the data may be lost, and there is now nothing you can do except log the possibility of a problem.

但是回到您的问题.确保关闭之前已写入和接收所有数据的方法是关闭套接字以在两端进行写入,然后在两端发出一次读取,这应返回流的末尾(recv()返回零),然后关闭套接字.这样一来,您就知道两个同位都已经关闭,并且已经读取了所有数据.如果recv()返回数据,则说明您的应用程序协议存在错误.我认为这应该全部以阻止模式进行.

However back to your problem. The way to assure all data has been written and received before closing is to shutdown the socket for writing at both ends, then issue a read at both ends, which should return end of stream (recv() returns zero), then close the socket. That way you know both peers got to the close at the same time, having already read all the data. If the recv() returns data you have a bug in your application protocol. This should all be carried out in blocking mode in my opinion.

这篇关于关闭插座的最佳做法. SO_LINGER还是关闭/关闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆