Bidirectional means data flows in both directions, whereas Unidirectional means data flows in only one direction. A socket is created as a bidirectional resource (capable of both sending and receiving), even if it is only used in a unidirectional manner in code. You can optionally use shutdown()
to close one direction of data flow if you are not going to use it (ie, shutdown(SD_SEND)
on a receive-only socket, or shutdown(SD_RECEIVE)
on a send-only socket).
A WebSocket is still a socket, just one that runs in a web browser, and whose transmitted data has to be framed in a particular format according to the WebSocket spec. A WebSocket can send/receive arbitrary data, just like an ordinary socket can, it just has to have the data wrapped in frames that need to be decoded on the receiving end.
bind()
, whether called on the client side or the server side (yes, it can be called on both), tells the OS which local IP/Port pair to associate with the socket before the connection is established. A socket is uniquely identified by its socket protocol type (UDP, TCP, etc), its local bound IP/Port pair, and its connected remote IP/Port pair. Network packets that do not match an established socket connection are discarded.
On the client side, calling bind()
is optional, as connect()
will bind implicitly if bind()
has not been called. bind()
is useful if the client has multiple network adapters installed and wants to specify which one to connect out with, or if the client must use a specific local port (dictated by data protocol, firewall rules, etc).
On the server side, bind()
is required, to establish the IP/Port that the server listens on to accept clients on.