/* * echoserver.c - A sequential echo server */ #include "csapp.h" void echo(int connfd); /* defined below */ void echo2(int connfd); /* defined below */ int main(int argc, char **argv) { int listenfd, connfd, port, clientlen=sizeof(struct sockaddr_in); struct sockaddr_in clientaddr; if (argc != 2) { fprintf(stderr, "usage: %s \n", argv[0]); exit(0); } port = atoi(argv[1]); listenfd = Open_listenfd(port); while (1) { connfd = Accept(listenfd, (SA *) &clientaddr, &clientlen); echo2(connfd); /* Service client */ Close(connfd); /* Close connection with client */ } } /* * echo - read, reverse and echo text lines until client closes connection * Solution to Exercise 6 */ void echo(int connfd) { size_t n; int i1, i2; char buf[MAXLINE]; char tmp; rio_t rio; Rio_readinitb(&rio, connfd); while(1) { n = Rio_readlineb(&rio, buf, MAXLINE); if(n <= 0) break; i1 = 0; i2 = n-2; /* indices to first and last character */ while (i1 <= i2) { tmp = buf[i1]; buf[i1] = buf[i2]; buf[i2] = tmp; i1++; i2--; } printf("server received %d bytes [%s]\n", n, buf); Rio_writen(connfd, buf, n); } } /* * echo2 - read, concatenate and echo pairs of text lines until client closes connection * Solution to Exercise 7 */ void echo2(int connfd) { size_t n1, n2; char buf[2*MAXLINE]; char buf2[MAXLINE]; rio_t rio; Rio_readinitb(&rio, connfd); while(1) { n1 = Rio_readlineb(&rio, buf, MAXLINE); if(n1 <= 0) break; /* Discard the end of line character '\n' */ n1--; buf[n1] = 0; /* Inform the server that the client is ready for the next string */ Rio_writen(connfd, "Next string, please\n", strlen("Next string, please\n")); n2 = Rio_readlineb(&rio, buf2, MAXLINE); if(n2 <= 0) break; /* Concatenate the two strings and write the result back to the client */ strcat(buf, buf2); Rio_writen(connfd, buf, n1+n2); printf("Server received %d bytes [%s]\n", n1+n2, buf); } }