Having the Client Request a Connection
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. It is not based on the size of a TCP packet.
#include "vmci_sockets.h"
#define BUFSIZE 4096
To compile on Windows, you must call the Winsock WSAStartup() function. See Preparing the Server for a Connection for sample code.
Socket() Function
In a vSockets application, obtain the new address family (domain) to replace AF_INET.
int afVMCI = VMCISock_GetAFValue();
if ((sockfd = socket(afVMCI, SOCK_STREAM, 0)) == -1) {
perror("socket");
goto exit;
}
VMCISock_GetAFValue() returns a descriptor for the vSockets address family if available.
Connect() Function
The connect() call requests a socket connection to the server specified by CID in the sockaddr_vm structure, instead of by the IP address in the sockaddr_in structure.
struct sockaddr_vm their_addr = {0};
their_addr.svm_family = afVMCI;
their_addr.svm_cid = SERVER_CID;
their_addr.svm_port = SERVER_PORT;
if ((connect(sockfd, (struct sockaddr *) &their_addr, sizeof their_addr)) == -1) {
perror("connect");
goto close;
}
The sockaddr_vm structure contains an element for the context ID (CID) to specify the virtual machine or host. The client making a connection should provide the CID of a remote virtual machine or host.
The port number is arbitrary, although server (listener) and client (connector) must use the same number, which must designate a port not already in use. Only privileged processes can use ports < 1024.
The connect() call allows you to use send() and recv() functions instead of sendto() and recvfrom(). The connect() call is not necessary for datagram sockets.
Send() Function
The send() call writes data to the server application. The client and server can communicate the length of data transmitted, or the server can terminate its recv() loop when the client closes its connection.
char send_buf[BUFSIZE];
/* Initialize send_buf with your data. */
if ((numbytes = send(sockfd, send_buf, sizeof send_buf, 0)) == -1) {
perror("send");
goto close;
}
Recv() Function
The recv() call reads data from the server application. Sometimes the server sends flow control information, so the client must be prepared to receive it. Use the same socket descriptor as for send().
char recv_buf[BUFSIZE];
if ((numbytes = recv(sockfd, recv_buf, sizeof recv_buf, 0)) == -1) {
perror("recv");
goto close;
}
Close() Function
The close() call shuts down a connection, given the original socket descriptor obtained from the socket() function. To compile on Windows, you must call the Winsock closesocket() instead of close().
#ifdef _WIN32
return closesocket(sockfd);
#else
return close(sockfd);
#endif
Poll() Information
Not all socket-based networking programs use poll(), but if they do, no changes are required.
Read() and Write()
The read() and write() socket calls are provided for convenience. They provide the same functionality as recv() and send().