- 论坛徽章:
- 0
|
/*
* name: tcp_slct.c
* written by saodrin zhang for test
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SVC_PORT 9999
int main_serv(int argc, char *argv[]);
int main_clnt(int argc, char *argv[]);
int main(int argc, char *argv[])
{
int ret;
if (argc == 1)
ret = main_serv(argc, argv);
else
ret = main_clnt(argc, argv);
return ret;
}
#define MAX_CNCT_NUM 8
#define BUF_SIZE 256
int main_serv(int argc, char *argv[])
{
int ret, i, k, n;
int len;
int inp_fd, sockfd, cnctfd, maxfd;
int cepfd[MAX_CNCT_NUM], cepnum, entry; /* clntfd[], clntnum */
int optval, sndFlag;
fd_set readfds, writefds;
struct sockaddr_in bindaddr; //servaddr
struct sockaddr_in cnctaddr; //clntaddr
struct timeval timeout;
char text[BUF_SIZE], buf[BUF_SIZE];
char sBuf[MAX_CNCT_NUM][BUF_SIZE];
maxfd = 0;
/*inp_fd = open("/dev/tty", O_RDONLY | O_NONBLOCK);*/
inp_fd = fileno(stdin);
printf("Inp_fd is %d\n", inp_fd); /* assert(inp_fd >= 0); */
fcntl(inp_fd, F_SETFL, fcntl(inp_fd, F_GETFL) | O_NONBLOCK);
/* assign the Protocol Family for communication */
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
printf("socket create error!\n");
return -1;
}
memset(&bindaddr, 0, sizeof(struct sockaddr_in));
/* AF_INET: Address Family */
bindaddr.sin_family = AF_INET;
/* INADDR_ANY: address of any interface owned by the host */
bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bindaddr.sin_port = htons(SVC_PORT);
bzero(&(bindaddr.sin_zero), 8); /* */
/* 置 socket 重新使用 */
optval = 1; /* option enable */
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof(optval)) = 0)
{
fcntl(inp_fd, F_SETFL, O_NONBLOCK);
}
if (sockfd >= 0)
{
fcntl(sockfd, F_SETFL, O_NONBLOCK);
}
text[0] = '\0';
for (i = 0; i = 0)
{
FD_SET(sockfd, &readfds);
maxfd = sockfd > maxfd ? sockfd : maxfd;
}
for (i = 0, n = 0; i 0)
{
FD_SET(cepfd, &readfds);
if (sBuf[0] != '\0')
{
/* printf("WR: FD_SET...\n"); */
FD_SET(cepfd, &writefds);
}
maxfd = cepfd > maxfd ? cepfd : maxfd;
n++;
}
}
ret = select(maxfd+1, &readfds, &writefds, NULL, &timeout);
//select error when ret = -1
if (ret == -1) printf("select error!\n");
//time out when ret = 0
//if (ret == 0) printf("select time out.\n");
//data coming when ret>0
if (ret > 0)
{
if (FD_ISSET(inp_fd, &readfds))
{
/*i = read(inp_fd, &ch, 1);
if('\n' == ch) continue;
else printf("Input is %c\n", ch);*/
n = read(inp_fd, text, BUF_SIZE);
if (n >= 0)
{
i = 0;
k = 0;
while (i %d: Connection from %s:%d\n", ++cepnum, \
inet_ntoa(cnctaddr.sin_addr), cnctaddr.sin_port);
fcntl(cnctfd, F_SETFL, O_NONBLOCK);
cepfd[entry] = cnctfd; /* client fd */
for (i = 0; i 0 && FD_ISSET(cepfd, &readfds))
{
n = read(cepfd, buf, BUF_SIZE);
if (n > 0)
{
buf[n] = '\0';
printf("RD cepfd[%d]: %s", i, buf);
k++;
if (buf[0] != '\0' && text[0] != '\0')
{
sprintf(sBuf, "%s + ", text);
strcat(sBuf, buf);
}
}
else if (n == 0)
{
printf("RD cepfd[%d]: peer is closed.\n", i);
shutdown(cepfd, SHUT_RDWR);
cepfd = -1;
close(cepfd);
cepnum--;
}
else
{
switch (errno)
{
case EAGAIN:
#if EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
k++;
break;
case EINTR:
/* we were stopped _before_ we had a connection */
case ECONNABORTED: /* this is a FreeBSD thingy */
/* we were stopped _after_ we had a connection */
k++;
break;
case EMFILE: /* out of fds */
k++;
break;
default:
perror("read");
cepfd = -1; /* close it */
cepnum--;
break;
} /* end switch (errno) */
} /* end if (n > 0) */
} /* end if (cepfd > 0 && FD_ISSET(cepfd, &readfds)) */
} /* end for (...; i 0 && FD_ISSET(cepfd, &writefds))
{
len = strlen(sBuf);
n = write(cepfd, sBuf, len);
if (n > 0) /* assert(n == len); */
{
printf("WR cepfd[%d]: %s", i, sBuf);
k++;
sBuf[0] = '\0';
}
else if (n == 0)
{
printf("WR cepfd[%d]: peer is closed.", i);
cepfd = -1;
cepnum--;
sBuf[0] = '\0';
}
else /* error */
{
switch (errno)
{
case EAGAIN:
#if EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
k++;
break;
case EINTR:
/* we were stopped _before_ we had a connection */
case ECONNABORTED: /* this is a FreeBSD thingy */
/* we were stopped _after_ we had a connection */
k++;
break;
case EMFILE: /* out of fds */
k++;
break;
default:
perror("read");
cepfd = -1; /* close it */
cepnum--;
break;
} /* end switch (errno) */
} /* end if (n > 0) */
} /* end if (cepfd > 0 && FD_ISSET(cepfd, &readfds)) */
} /* end for (...; i 0) */
}
return 0;
}
int main_clnt(int argc, char *argv[])
{
int ret, i, n;
int len;
int inp_fd, sockfd, cnctfd, maxfd;
int cepfd[MAX_CNCT_NUM], cepnum, entry;
int optval, sndFlag;
fd_set readfds, writefds;
struct sockaddr_in bindaddr; //local client address
struct sockaddr_in cnctaddr; //remote server address
struct timeval timeout;
struct hostent *host;
struct in_addr servAddr;
unsigned long servIP;
char text[BUF_SIZE], buf[BUF_SIZE];
if (argc h_addr_list[0], sizeof(struct in_addr));
servIP = ntohl(servAddr.s_addr);
printf("destIP = 0x%x\n", servIP);
}
else
{
printf("Error: gethostbyname\n");
return -1;
}
/*inp_fd = open("/dev/tty", O_RDONLY | O_NONBLOCK);*/
inp_fd = fileno(stdin);
printf("Inp_fd is %d\n", inp_fd); /* assert(inp_fd >= 0); */
fcntl(inp_fd, F_SETFL, fcntl(inp_fd, F_GETFL) | O_NONBLOCK);
maxfd = inp_fd;
/* assign the Protocol Family for communication */
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
printf("socket create error!\n");
return -1;
}
memset(&bindaddr, 0, sizeof(struct sockaddr_in));
/* AF_INET: Address Family */
bindaddr.sin_family = AF_INET;
/* INADDR_ANY: address of any interface owned by the host */
bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bindaddr.sin_port = htons(SVC_PORT);
bzero(&(bindaddr.sin_zero), 8); /* */
/* 置 socket 重新使用 */
optval = 1; /* option enable */
//if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof(optval)) maxfd ? cnctfd : maxfd;
while (1)
{
timeout.tv_sec = 1;
timeout.tv_usec = 0;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_SET(inp_fd, &readfds);
FD_SET(cnctfd, &readfds);
if (sndFlag != 0) FD_SET(cnctfd, &writefds);
ret = select(maxfd+1, &readfds, &writefds, NULL, &timeout);
//select error when ret = -1
if (ret == -1) printf("select error\n");
//time out when ret = 0
//if (ret == 0) printf("select time out\n");
//data coming when ret>0
if (ret > 0)
{
if (FD_ISSET(inp_fd, &readfds))
{
/*i = read(inp_fd, &ch, 1);
if('\n' == ch) continue;
else printf("Input is %c\n", ch);*/
n = read(inp_fd, text, BUF_SIZE);
if (n >= 0)
{
text[n] = '\0';
}
else
{
printf("RD STDIN error!\n");
text[0] = '\0';
}
if ('\n' == text[0]) continue;
else printf("Inputed: %s", text);
if ('q' == text[0]) break;
else sndFlag = 1;
}
if (FD_ISSET(cnctfd, &readfds))
{
n = recv(cnctfd, buf, BUF_SIZE, MSG_DONTROUTE);
if (n > 0)
{
buf[n] = '\0';
printf("Recv OK: %s", buf);
}
else if (n == 0) /* peer is closed */
{
printf("Peer is closed ...\n");
shutdown(cnctfd, SHUT_RDWR);
close(cnctfd);
break;
}
else
{
printf("Recv error!\n");
}
}
if (FD_ISSET(cnctfd, &writefds))
{
if ((n = strlen(text)) > 0)
{
if ((i = send(cnctfd, text, n, MSG_DONTROUTE)) != n)
{
printf("Try to send again...\n");
sndFlag = 1;
}
else
{
printf("Send OK: %s", text);
sndFlag = 0;
}
}
else
{
sndFlag = 0; /* FD_CLR(cnctfd, &writefds); */
printf("Nothing to be sent\n");
if ((i = write(cnctfd, "...\n", 4)) != 4)
perror("Test write");
} /* end if ((n = strlen(text)) > 0) */
} /* end if (FD_ISSET(cnctfd, &writefds)) */
} /* end if (ret > 0) */
} /* end while (1) */
return ret;
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/3771/showart_2147699.html |
|