Sockets will act much like reading and writing to files. In one program the server will write information to a socket, and in the other program the client will be able to read that information. It is possible for information exchange to be in both directions once the socket connection has been established.
This page is only an assist to get students involved in Supercomputer Applications started with sockets. For a more complete and well organized tutorial, check out the pages by Brian "Beej" Hall from his website on networks and sockets:
#include <sys/types.h> #include <sys/socket.h> int socket(int family, int type, int protocol)Where:
sockfd = socket(AF_NET, SOCK_STREAM, 0);
#include <netinet/in.h> //for sockaddr_in structure #include <netdb.h> //for hostent structure #define MYPORT 6994 // This is an arbitrary number struct sockaddr_in myaddr; //data structure to hold socket info char ip_addr[MAXIP]; //ip address such as 198.38.17.1 char hostname[MAXNAME]; //host name such as station1.tjhsst.eduSince the data structures could have garbage values that could cause problems, the memset() function can be used to initialize all values to zero. An alternative function, bzero(), accomplishes the same thing but this function is being deprecated.
memset(&myaddr, 0, sizeof(myaddr)); //clears out data structure myaddr.sin_family = AF_INET; //fill in address family myaddr.sin_port = htons(MYPORT); //assign port in network byte order gethostname(hostname,sizeof(hostname)); //this gets the hostname of the local computer struct hostent *hp; // pointer to host entity hp=gethostbyname(hostname); // assign the value memcpy(addr.sin_addr, hp->h_addr, hp->h_length); //copy some data from sockaddr_in to hostent strcpy(ip_addr,inet_ntoa(*((struct in_addr *)hp->h_addr))); //get the IP Address from the hostent structure
On the server side, the following is typical:
//sockfd has been initialized as previously stated //myaddr has been initialized as previously stated bind(sockfd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr)); //this binds a waiting socket to the socket file descriptor listen(sockfd,3); //this listens on the socket for up to three(3) incoming messages from other sockets int newfd=accept(sockfd,NULL,NULL); //this pauses the program and accepts the first nonlocal socket to make a connection //at which point the program continues //newfd = the file descriptor for the new socket connection which becomes establishedOn the client side, the following connects to the server.
//sockfd and myaddr have already been initialized connect(sockfd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr));For the actual data transfer, a character array buffer needs to be created to hold the information that is being received. The functions that send the data are typically send() and recv(), although read() and write() can also be used.
On the server side the following is typical:
send(newfd, message, strlen(message), 0)On the client side this is how the program receives the message:
#define MAXDATA 100 char buffer[MAXDATA]; numbytes=recv(sockfd, buffer, MAXDATA, 0)Similarly, read and write could be used.
read(sockfd, buffer, MAXDATA); write(sockfd, buffer, sizeof(buffer))
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Error getting socket descriptor"); exit(1); }The server program in the following example must be started first, and then it waits for the client program on another machine to connect to it. Once the connection is made, the person sitting at the server program types in a string of letters, and that string is then printed out on the client's terminal.
The server and client programs below demonstrate simple one way communication. However, SOCK_STREAM supports two way communication through the same port, so by adding a send() function to the client side and recv() to the server side, messages can be sent both ways through the same socket creating a simple "chat" program.