server.c
#include
#include
#include
#include
#include
#include
#include "wrap.h"
#define SERV_PORT 8888
int main()
{
int opt = 1;
int i, j, n, maxi;
int nready, client[FD_SETSIZE];
int maxfd, listenfd, connfd, sockfd;
char buf[BUFSIZ], clie_IP[INET_ADDRSTRLEN];
struct sockaddr_in clie_addr, serv_addr;
socklen_t clie_addr_len;
fd_set read_set, allset;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family= AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port= htons(SERV_PORT);
Bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
Listen(listenfd, 128);
maxfd = listenfd;
maxi = -1;
for (i = 0; i < FD_SETSIZE; ++i)
{
client[i] = -1;
}
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
while (1)
{
read_set = allset;
nready = select(maxfd+1, &read_set, NULL, NULL, NULL);
if (nready < 0)
{
perr_exit("select error");
}
if (FD_ISSET(listenfd, &read_set))
{
clie_addr_len = sizeof(clie_addr);
connfd = Accept(listenfd, (struct sockaddr *)&clie_addr, &clie_addr_len);
printf("received from %s at PORT %d\n",
inet_ntop(AF_INET, &clie_addr.sin_addr, clie_IP, sizeof(clie_IP)),
ntohs(clie_addr.sin_port));
for (i = 0; i < FD_SETSIZE; ++i)
{
if (client[i] < 0)
{
client[i] = connfd;
break;
}
}
if (FD_SETSIZE == i)
{
printf("client numbers over\n");
exit(1);
}
FD_SET(connfd, &allset);
if (connfd > maxfd)
{
maxfd = connfd;
}
if (i > maxi)
{
maxi = i;
}
if (--nready == 0)
{
continue;
}
}
for (i = 0; i <= maxi; ++i)
{
if ((sockfd = client[i]) < 0)
{
continue;
}
if (FD_ISSET(sockfd, &read_set))
{
n = Read(sockfd, buf, sizeof(buf));
if (0 == n)
{
Close(sockfd);
FD_CLR(sockfd, &allset);
client[i] = -1;
}
else if (n > 0)
{
for (j = 0; j < n; ++j)
{
buf[j] = toupper(buf[j]);
}
Write(sockfd, buf, n);
Write(STDOUT_FILENO, buf, n);
}
if (--nready == 0)
{
break;
}
}
}
}
Close(listenfd);
return 0;
}
wrap.h
#include
#include
#include
#include
#include
void perr_exit(const char *str)
{
perror(str);
exit(-1);
}
int Socket(int family, int type, int protocol)
{
int n;
n = socket(family, type, protocol);
if (n < 0)
{
perr_exit("socket error");
}
return n;
}
int Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
int n;
n = bind(fd, sa, salen);
if (n < 0)
{
perr_exit("bing error");
}
return n;
}
int Listen(int fd, int backlog)
{
int n;
n = listen(fd, backlog);
if (n < 0)
{
perr_exit("listen error");
}
return n;
}
int Connect(int fd, const struct sockaddr *sa, socklen_t salen)
{
int n;
n = connect(fd, sa, salen);
if (n < 0)
{
perr_exit("connect error");
}
return n;
}
int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
int n;
again:
n = accept(fd, sa, salenptr);
if (n < 0)
{
if (errno == ECONNABORTED || errno == EINTR)
{
goto again;
}
else
{
perr_exit("accept error");
}
}
return n;
}
ssize_t Read(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
again:
n = read(fd, ptr, nbytes);
if (-1 == n)
{
if (EINTR == errno)
{
goto again;
}
else
{
return -1;
}
}
return n;
}
ssize_t Write(int fd, const void *ptr, size_t nbytes)
{
ssize_t n;
again:
n = write(fd, ptr, nbytes);
if (-1 == n)
{
if (EINTR == errno)
{
goto again;
}
else
{
return -1;
}
}
return n;
}
int Close(int fd)
{
int n;
n = close(fd);
if (-1 == n)
{
perr_exit("close error");
}
return n;
}