/* client4_select.c client skeleton for ex4 17 */ /* version to recv everything until user give more input or connection is closed */ #include #include #include #include #include #include #include #include #include #include /* official network end-of-line is CR LF */ #define EOL "\015\012" /* size of the send/receive buffer */ #define MAXMSG 1000 /* this macro can be used to check errors, see server.c for examples */ #define ERRORCHEK(var, value, command) if (var == value) { \ perror(command); \ exit(1); \ } int main(int argc, char *argv[]) { int ssock; /* socket to server */ int numbytes, status; char rbuf[MAXMSG]; /* receive buffer */ char sbuf[MAXMSG*2]; /* send buffer */ struct hostent *he; struct sockaddr_in se_addr; /* server address */ int sin_size = sizeof(struct sockaddr_in); /* convenience constant */ fd_set fds, orig_fds; int fdmax; int port = 9876; /* default port */ if (argc < 2) { fprintf(stderr,"usage: %s hostname [port]\n", argv[0]); exit(1); } /* get server address */ he=gethostbyname(argv[1]); if (he == NULL) { perror("gethostbyname"); exit(1); } /* port as optional second parameter */ if (argc > 2) port = atoi(argv[3]); /* get socket */ ssock = socket(AF_INET, SOCK_STREAM, 0); if (ssock == -1) { perror("socket"); exit(1); } /* contruct address struct */ se_addr.sin_family = AF_INET; se_addr.sin_port = htons(port); /* NBO */ se_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(&(se_addr.sin_zero), '\0', 8); /* connect to the server */ status = connect(ssock, (struct sockaddr *)&se_addr, sin_size); ERRORCHEK(status, -1, "connect"); /* set up file descriptor set */ FD_ZERO(&orig_fds); FD_SET(ssock, &orig_fds); FD_SET(STDIN_FILENO, &orig_fds); /* for keyboard */ fdmax = ssock; /* main loop */ do { /* wait until user of ssock has something to give */ /* copy to temporary fds, select() changes the set */ fds = orig_fds; status = select(fdmax+1, &fds, NULL, NULL, NULL); ERRORCHEK(status, -1, "select"); /* user input */ if (FD_ISSET(STDIN_FILENO, &fds)) { fgets(sbuf, MAXMSG-1, stdin); /* replace NL with CRNL */ strcpy(sbuf+strlen(sbuf)-1, EOL); /* single send for short messages is ok */ numbytes = send(ssock, sbuf, strlen(sbuf), 0); if (numbytes == -1) { perror("send"); exit(1); } else if (numbytes != strlen(sbuf)) printf("Only %d bytes sent! Should have used repeated send...\n", numbytes); } /* if stdin */ /* incoming data */ if (FD_ISSET(ssock, &fds)) { /* receive */ numbytes=recv(ssock, rbuf, MAXMSG-1, 0); if (numbytes == -1) { perror("recv"); exit(1); } if (numbytes == 0) { printf("Connectino closed\n"); break; } /* terminate message to make a string */ rbuf[numbytes] = '\0'; printf("Received: %s",rbuf); } /* if ssock */ } while (!strstr(sbuf, "quit")); close(ssock); exit(0); }