At the top of your application, include vmci_sockets.h and declare a constant for the socket buffer size. In the example below,
BUFSIZE defines the socket buffer size. The number 4096 is a good choice for efficiency on multiple platforms. It is not based on the size of a TCP packet, which is usually smaller.
VMCISock_GetAFValue() returns a descriptor for the vSockets address family if available.
To set a new value for a socket option, call the setsockopt() function. To get a value, call
getsockopt().
Parameters setBuf and
getBuf must be declared 64 bit, even on 32-bit systems.
This bind() call associates the stream socket with the network settings in the
sockaddr_vm structure, instead of the
sockaddr_in structure.
The sockaddr_vm structure contains an element for the context ID (CID), which specifies the virtual machine. For the client this is the local CID. For the server (listener), this could be any connecting virtual machine. Both
VMADDR_CID_ANY and
VMADDR_PORT_ANY are predefined so that at bind or connection time, the appropriate CID and port number are filled in from the client.
VMADDR_CID_ANY is replaced with the CID of the virtual machine and
VMADDR_PORT_ANY provides an ephemeral port from the nonreserved range (>= 1024).
The bind() function is the same as for a regular TCP sockets application.
The listen() call prepares to accept incoming client connections. The
BACKLOG macro predefines the number of incoming connection requests that the system accepts before rejecting new ones. This function is the same as
listen() in a regular TCP sockets application.
The accept() call waits indefinitely for an incoming connection to arrive, creating a new socket (and stream descriptor
newfd) when it does. The structure
their_addr gets filled with connection information.
The select() call enables a process to wait for events on multiple file descriptors simultaneously. This function hibernates, waking up the process when an event occurs. You can specify a timeout in seconds or microseconds. After timeout, the function returns zero. You can specify the read, write, and exception file descriptors as
NULL if the program can safely ignore them.
The recv() call reads data from the client application. The server and client can communicate the length of data transmitted, or the server can terminate its
recv() loop when the client closes its connection.
The send() call writes data to the client application. Server and client must communicate the length of data transmitted, or agree beforehand on a size. Often the server sends only flow control information to the client.
Given the original socket descriptor obtained from the socket() call, the
close() call closes the socket and terminates the connection if it is still open. Some server applications close immediately after receiving client data, while others wait for additional connections. To compile on Windows, you must call the Winsock
closesocket() instead of
close().
The shutdown() function is like
close(), but shuts down the connection.
Not all socket-based networking programs use poll(), but if they do, no changes are required. The
poll() function is like
select(). See
Select() Function for related information.
The read() and
write() socket calls are provided for convenience. They provide the same functionality as
recv() and
send().
The getsockname() function retrieves the local address associated with a socket.