What are Sockets?
Definition of a Socket
A Socket is an endpoint for communication through the use of file descriptors. Sockets are used to send/receive data to/from other processes on local or external machines.
Logically, sockets are created in a communication domain, which is an abstraction grouping sets of properties for communication through sockets. Communication domains include the UNIX domain and internet domain (among others which are not widely used). Sockets only connect with other sockets in the same domain. Unix domain sockets are used for inter-process communication (IPC). They are Unix-specific and their communication does not use the file system, but rather buffers in kernel memory. As of right now (Sept-5-2008), this kind of socket IPC is not available in U++ because it is not supported across multiple platforms (Ie. Windows). Although, it is possible to leverage internet sockets for scalable applications that can communicate on the same computer (IPC) or networked computers. U++ has been built to abstract away the low level platform-specific details of this form of socket communication.
There are 2 commonly used socket types: SOCK_STREAM and SOCK_DGRAM. SOCK_STREAM indicates that data comes across the socket as a stream of characters in a connection-oriented protocol. SOCK_DGRAM indicates that data comes in datagrams (connectionless protocols). U++ uses SOCK_STREAM sockets for transferring data. These sockets have the ability to queue incoming connection requests. This means that you can be dealing with one connection and not worry that others are being denied. Although, there is a threshold value (default of 5) queued connection per socket; this value can be set by the user. The listen_count parameter of the ServerSocket() function allows you to customize this value.
A socket can linger after a close operation for a specified period of time to ensure that all data is read/written. This gives the program time to finish reading from or writing to buffers after a close method has been called. Usually, this setting can be more important for non-blocking operations. The close will complete either after all data has been read/written or the linger time has elapsed.
Blocking vs Non-Blocking
Normal socket operations are blocking operations; this means that program waits until a socket operation completes. For example, a Read operation on a socket is not complete until some data has been sent to the socket to be read. The Read operation will wait for this data; the program is "blocked" until the request for data has been satisfied.
On the other hand, if set to non-blocking, socket operations will return to the program immediately. In the case of the Read operation, it will return any information already in the socket's read buffer. Otherwise, if no data is immediately available, it will return with an error indicating that there is no data to be read. The developer has to take this difference into account, as non-blocking operations require the application to recognize the error condition and handle the error.
The same is true for the write (send) operation. When you write to a socket, it puts the data into a buffer.After the data has been read by the opposite side, it is removed from the buffer. For a non-blocking operation, if the buffer is "full", and the write/send operation is performed, the system will return the error 'Operation Would Block". If it was a blocking operation, the program would wait until there was room in the buffer.
For a non-blocking Accept operation, if there isn't already a client making a connection with the accepting socket, it will return 'Operation Would Block' (EWOULDBLOCK), to tell you that it can't complete the Accept operation without waiting for a connection.
For a non-blocking connect operation, if you try to call connect() and the a connection cannot be established right away, it will return the error code for 'Operation In Progress'. When you call connect again, the error message could be 'Operation Already In Progress' to let you know that it's still trying to connect, or it may give you a successful return code, telling you that the connection has been made.