what does readable/writable mean in a socket file descriptor? And why regular files don't bother with that?

℡╲_俬逩灬. 提交于 2020-01-10 04:31:09

问题


Since I'm new in learning libev recently, there's a readable/writable concept in a io_watcher that I don't quite understand. For my knowledge there's a parameter in linux system programming:

O_ASYNC

A signal (SIGIO by default) will be generated when the specified file becomes readable or writable. This flag is available only for terminals and sockets, not for regular files.

So, since a regular file won't bother with readable/writable, what readable/writable really mean in socket programming? And what measure did kernel do to find out whether a socket file descriptor is readable?

Considering the everything-is-a-file philosophy, does every socket descriptor with different descriptor number actually point to the same file? If so,can I consider the readable/writable problem is caused by the synchronisation?

OK it seems that I'v asked a silly question. What I really mean is that both socket and regular file read and write via file descriptor, so why socket descriptor got a readable/writable concept but regular file doesn't. Since EJP told me that this is because the buffer and each descriptor got their own pair of buffers, here's my conclusion: readable/writable concept is for buffers, if a buffer is empty, it's unreadable, while it is full, it's unwritable. readable and writable have nothing to do with synchronisation, and since regular file don't have a buffer, it is always readable and writable.

And there are more questions: when saying receive buffer, this buffer is not the same thing in int recv(SOCKET socket, char FAR* buf, int len, int flags);, right?


回答1:


Readable means there is data or a FIN present in the socket receive buffer.

Writable means there is space available in the socket send buffer.

Files don't have socket send or receive buffers.

Considering the everything-is-a-file philosophy

What philosophy is that?

does every socket descriptor with different descriptor number actually point to the same file?

What file? Why would they point to the same anything? Question doesn't make sense.

I'm confused with one thing: when a socket is created, the descriptor is actually point to the receive and send buffers of the socket

It 'points to' a lot of things: a source address, a target address, a source port, a target point, a pair of buffers, a set of counters and timers, ...

not the file represent the net hardware.

There is no such thing as 'the file represent[ing] the net hardware', unless you're talking about the device driver entry in /dev/..., which is barely relevant. A TCP socket is an endpoint of a connection. It is specific to that connection, to TCP, to the source and target addresses and ports, ...




回答2:


This question is specifically addressed in Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition) [W. Richard Stevens, Bill Fenner, Andrew M. Rudoff] (see it here. I'll add some minor edits for enhanced readability):

Under What Conditions Is a Descriptor Ready?

[...] The conditions that cause select to return "ready" for sockets [are]:

1. A socket is ready for reading if any of the following four conditions is true:

  • The number of bytes of data in the socket receive buffer is greater than or equal to the current size of the low-water mark for the socket receive buffer. A read operation on the socket will not block and will return a value greater than 0 (i.e., the data that is ready to be read). [...]
  • The read half of the connection is closed (i.e., a TCP connection that has received a FIN). A read operation on the socket will not block and will return 0 (i.e., EOF).
  • The socket is a listening socket and the number of completed connections is nonzero. [...]
  • A socket error is pending. A read operation on the socket will not block and will return an error (–1) with errno set to the specific error condition. [...]

2. A socket is ready for writing if any of the following four conditions is true:

  • The number of bytes of available space in the socket send buffer is greater than or equal to the current size of the low-water mark for the socket send buffer and either: (i) the socket is connected, or (ii) the socket does not require a connection (e.g., UDP). This means that if we set the socket to nonblocking, a write operation will not block and will return a positive value (e.g., the number of bytes accepted by the transport layer). [...]
  • The write half of the connection is closed. A write operation on the socket will generate SIGPIPE.
  • A socket using a non-blocking connect has completed the connection, or the connect has failed.
  • A socket error is pending. A write operation on the socket will not block and will return an error (–1) with errno set to the specific error condition. [...]

3. A socket has an exception condition pending if there is out-of-band data for the socket or the socket is still at the out-of-band mark.

[Notes:]

  • Our definitions of "readable" and "writable" are taken directly from the kernel's soreadable and sowriteable macros on pp. 530–531 of TCPv2. Similarly, our definition of the "exception condition" for a socket is from the soo_select function on these same pages.

  • Notice that when an error occurs on a socket, it is marked as both readable and writable by select.

  • The purpose of the receive and send low-water marks is to give the application control over how much data must be available for reading or how much space must be available for writing before select returns a readable or writable status. For example, if we know that our application has nothing productive to do unless at least 64 bytes of data are present, we can set the receive low-water mark to 64 to prevent select from waking us up if less than 64 bytes are ready for reading.

  • As long as the send low-water mark for a UDP socket is less than the send buffer size (which should always be the default relationship), the UDP socket is always writable, since a connection is not required.

A related read, from the same book: TCP socket send buffer and UDP socket (pseudo) send buffer



来源:https://stackoverflow.com/questions/31314547/what-does-readable-writable-mean-in-a-socket-file-descriptor-and-why-regular-fi

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!