客户端的代码:
#include "csapp.h" int main(int argc, char **argv) { int clientfd, port; char *host, buf[MAXLINE]; rio_t rio; if (argc != 3) { fprintf(stderr, "usage: %s <host> <port>\n", argv[0]); exit(0); } host = argv[1]; port = atoi(argv[2]); printf("----000\n"); clientfd = Open_clientfd(host, port); printf("----1111\n"); Rio_readinitb(&rio, clientfd); while (Fgets(buf, MAXLINE, stdin) != NULL) { Rio_writen(clientfd, buf, strlen(buf)); printf("---test---\n"); Rio_readlineb(&rio, buf, MAXLINE); Fputs(buf, stdout); } Close(clientfd); exit(0); }
服务器的代码:
#include "csapp.h" void echo(int connfd) { size_t n; char buf[MAXLINE]; rio_t rio; Rio_readinitb(&rio, connfd); while ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) { printf("server received %lu by66tes \n", n); printf("%s\n", buf); // Rio_writen(connfd, buf, n); } } int main(int argc, char **argv) { int listenfd, connfd, port, clientlen; struct sockaddr_in clientaddr; struct hostent *hp; char *haddrp; if (argc != 2) { fprintf(stderr, "usage: %s <port> \n", argv[0]); exit(0); } port = atoi(argv[1]); listenfd = Open_listenfd(port); while (1) { clientlen = sizeof(clientaddr); connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); /* determine the domin name and IP address of the client. */ hp = Gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, sizeof(clientaddr.sin_addr.s_addr), AF_INET); haddrp = inet_ntoa(clientaddr.sin_addr); printf("server connect to %s (%s)\n", hp->h_name, haddrp); echo(connfd); Close(connfd); } exit(0); }
也可以用select 来实现这个服务器代码.
#include "csapp.h" void echo(int connfd); void command(void); int main(int argc, char **argv) { int listenfd, connfd, port; socklen_t clientlen = sizeof(struct sockaddr_in); struct sockaddr_in clientaddr; fd_set read_set, ready_set; if (argc != 2) { fprintf(stderr, "usage: %s <port>\n", argv[0]); exit(0); } port = atoi(argv[1]); listenfd = Open_listenfd(port); FD_ZERO(&read_set); /* clear read set. */ FD_SET(STDIN_FILENO, &read_set); /* add stdin to read set. */ FD_SET(listenfd, &read_set); /* add listenfd to read set. */ //printf("hhhhhhhhhhhhhhhhhhhhhhh\n"); while (1) { ready_set = read_set; // printf("---------------------: %d\n", listenfd + 1); Select(listenfd + 1, &ready_set, NULL, NULL, NULL); // printf("11111111111111111111111111\n"); if (FD_ISSET(STDIN_FILENO, &ready_set)) { command(); /* read command line from stdin. */ } // printf("------------------------\n"); if (FD_ISSET(listenfd, &ready_set)) { connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); echo(connfd); /* echo client input until EOF. */ Close(connfd); } } } void command(void) { char buf[MAXLINE]; if (!Fgets(buf, MAXLINE, stdin)) exit(0); /* EOF */ printf("%s\n", buf); /* Process the input command. */ } void echo(int connfd) { size_t n; char buf[MAXLINE]; rio_t rio; Rio_readinitb(&rio, connfd); while ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) { printf("server received %lu by66tes \n", n); //printf("%s\n", buf); Rio_writen(connfd, buf, n); } }
这是书上的源码,很容易看明白, 这样就可以大概了解socket的基本方法。以下 运行
./echoserver 8080&
./echoclient ubuntu-64bit-compile 8080
这样就可以啦。