下面用一个例子来测试一下(根据UNP的例子改编)。
1. daytimecli.c
#include "unp.h" #include <sys/select.h> int main(int argc, char **argv) { int sockfd, n; char recvline[MAXLINE + 1]; struct sockaddr_in servaddr; if (argc != 2) err_quit("usage: a.out <IPaddress>"); if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) err_sys("socket error"); fd_set writeFd, readFd; FD_ZERO(&writeFd); FD_ZERO(&readFd); FD_SET(sockfd, &writeFd); FD_SET(sockfd, &readFd); if(select(sockfd + 1, &readFd, &writeFd, NULL, NULL) == -1) { printf("select fails at line %d\n", __LINE__); } else { if(FD_ISSET(sockfd, &readFd)) { printf("[client] After creation, socket is readable\n"); } if(FD_ISSET(sockfd, &writeFd)) { printf("[client] After creation, socket is writable\n"); } } FD_ZERO(&writeFd); FD_ZERO(&readFd); FD_SET(sockfd, &writeFd); FD_SET(sockfd, &readFd); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(13); /* daytime server */ if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) err_quit("inet_pton error for %s", argv[1]); printf("[client]: connect to server\n"); if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) err_sys("connect error"); if(select(sockfd + 1, &readFd, &writeFd, NULL, NULL) > 0) { if(FD_ISSET(sockfd, &readFd)) { printf("[client] After connect, socket is readable\n"); } if(FD_ISSET(sockfd, &writeFd)) { printf("[client] After connect, socket is writable\n"); } } FD_ZERO(&readFd); FD_SET(sockfd, &readFd); if(select(sockfd + 1, &readFd, NULL, NULL, NULL) > 0) { if(FD_ISSET(sockfd, &readFd)) { printf("[client] now sockfd is readable again\n"); } } #if 0 while ( (n = read(sockfd, recvline, MAXLINE)) > 0) { recvline[n] = 0; /* null terminate */ if (fputs(recvline, stdout) == EOF) err_sys("fputs error"); } if (n < 0) err_sys("read error"); #endif n = recv(sockfd, recvline, MAXLINE, MSG_DONTWAIT | MSG_NOSIGNAL); if(n > 0) { printf("[client] receive %d bytes\n", n); int nread = ioctl(sockfd, FIONREAD, &nread); printf("[client] ioctl return: nread = %d\n", nread); if(nread > 0) { //printf("still there is data %d bytes\n", nread); } else { n = recv(sockfd, recvline, 1, MSG_PEEK | MSG_DONTWAIT); int local_errno = errno; if(local_errno != EAGAIN || n == 0) { printf("[client] server is closed\n"); } else { printf("[client] errno: %d peek data is %d bytes\n", local_errno, n); } } } exit(0); }
#include "unp.h" #include <time.h> #include <sys/select.h> int main(int argc, char **argv) { int listenfd, connfd; struct sockaddr_in servaddr; char buff[MAXLINE]; time_t ticks; listenfd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(13); /* daytime server */ Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); Listen(listenfd, LISTENQ); fd_set readFd, writeFd; FD_ZERO(&writeFd); FD_ZERO(&readFd); FD_SET(listenfd, &writeFd); FD_SET(listenfd, &readFd); if(select(listenfd + 1, &readFd, &writeFd, NULL, NULL) > 0) { if(FD_ISSET(listenfd, &readFd)) { printf("[server] listen fd is readable\n"); } if(FD_ISSET(listenfd, &writeFd)) { printf("[server] listen fd is writable\n"); } } for ( ; ; ) { printf("[server]: call accept\n"); connfd = Accept(listenfd, (SA *) NULL, NULL); FD_ZERO(&writeFd); FD_ZERO(&readFd); FD_SET(connfd, &writeFd); FD_SET(connfd, &readFd); if(select(connfd + 1, &readFd, &writeFd, NULL, NULL) > 0) { if(FD_ISSET(connfd, &readFd)) { printf("[server]: connected fd is readable\n"); } if(FD_ISSET(connfd, &writeFd)) { printf("[server] connected fd is writable\n"); } } // printf("server accept connection\n"); // close(connfd); // continue; ticks = time(NULL); snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); printf("[server] write data to client\n"); Write(connfd, buff, strlen(buff)); printf("[server]: server-side socket closed\n"); Close(connfd); //printf("server-side socket closed\n"); } }
@taotao:~/code/unpv13e/intro$ sudo sh -c "./daytimetcpsrv &" charles@taotao:~/code/unpv13e/intro$ sudo ./daytimetcpcli 192.168.2.12 [client] After creation, socket is readable [client] After creation, socket is writable [client]: connect to server [client] After connect, socket is writable [server] listen fd is readable [server]: call accept [server] connected fd is writable [server] write data to client [client] now sockfd is readable again [server]: server-side socket closed [server]: call accept [client] receive 26 bytes [client] ioctl return: nread = 0 [client] server is closed