//////////////////////////////////////////////////////////// // // File: client.cc // Description: a sample client of the infobus-socket protocol // Author: Arturo Crespo // Created: Aug 15, 1994 // Modified: // Language: C++ // Package: N/A // Status: Experimental (Do Not Distribute) // // Notes: // * This program is inspired from the many examples of: // Unix Network Programming by W. Richard Stevens // For more information on BSD Sockets, please refer to // chapter 6 of this book. //////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include const char* SERVER_ADDR = "171.64.75.99"; // Mullet.Stanford.edu const int SERVER_PORT = 30169; const int BUFFER_SIZE = 4096; // forward declarations void interoperate( int sockfd ); int writen( int fd, char* ptr, int nbytes); //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// // // main // //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// int main() { int sockfd; struct sockaddr_in serverAddress; // fill in the structure serverAddress witht the address of the // infobus-socket server bzero((char*)&serverAddress, sizeof(serverAddress)); serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = inet_addr(SERVER_ADDR); serverAddress.sin_port = htons(SERVER_PORT); // open a TCP socket if ((sockfd=socket( AF_INET, SOCK_STREAM, 0))<=0) { perror( "Can't open socket "); exit(1); } // connect to the server if ( connect(sockfd, (struct sockaddr*) &serverAddress, sizeof(serverAddress)) <0 ) { perror( "Can't connect to server "); exit(1); } interoperate( sockfd ); // this function does the interoperation // with the infobus close(sockfd); } //////////////////////////////////////////////////////////// // // interoperate: // // Desc: this is a very simple interoperation function, it just // sends to the infobus-socket server whatever the user // types in stdin and copies to stdout everything that // the server sends to the client // In: sockfd - the socket file descripton // //////////////////////////////////////////////////////////// void interoperate( int sockfd ) { int nFound; int nRead; char buffer[BUFFER_SIZE]; fd_set readMask; FD_ZERO(&readMask); for (;;) { FD_SET(0, &readMask); // check stdin FD_SET(sockfd, &readMask); // check the socket nFound = select( sockfd+1, &readMask, (fd_set*)0, (fd_set*)0, (struct timeval*)0); if (nFound<0) { perror("Error in Select "); exit(1); } if (FD_ISSET(0,&readMask)) { // is there data in stdin? nRead = read(0, buffer, BUFFER_SIZE); if (nRead<0) { perror("Error reading stdin "); exit(1); } else if (nRead==0) { break; // we read EOF, we are done! } else { if (writen(sockfd, buffer, nRead)!=nRead) { perror("Error writing to the socket "); exit(1); } } } if (FD_ISSET(sockfd,&readMask)) { // is there data in the socket? nRead = read(sockfd, buffer, BUFFER_SIZE); if (nRead<=0) { // error or EOF break; } else { if (write(1, buffer, nRead)!=nRead) { perror("Error writing to stdout "); exit(1); } } } } fprintf(stderr,"Connection to Infobus-Socket server closed\n"); } //////////////////////////////////////////////////////////// // // writen // // Desc: Writes n bytes to a file descriptor descriptor. // Useful when dealing with sockets as the call // write(sockfd,buffer,n) doesn't guarantee that n // bytes will be written to the buffer // In: fd - the file descriptor // ptr - pointer to the data to be written // nbytes - number of bytes to write // Out: - the number of bytes written // //////////////////////////////////////////////////////////// int writen( int fd, char* ptr, int nbytes) { int nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write( fd, ptr, nleft ); if (nwritten<=0) { return nwritten; // error } nleft -= nwritten; ptr += nwritten; } return (nbytes - nleft); }