server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include "wrap.h"
#define OPEN_MAX 1024
#define SERV_PORT 8888
int main()
{
ssize_t n;
int opt = 1;
int i, j, maxi;
int nready;
int listenfd, connfd, sockfd;
char buf[BUFSIZ], clie_IP[INET_ADDRSTRLEN];
struct sockaddr_in clie_addr, serv_addr;
socklen_t clie_addr_len;
struct pollfd client[OPEN_MAX];
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);
client[0].fd = listenfd;
client[0].events = POLLIN;
maxi = 0;
for (i = 1; i < OPEN_MAX; ++i)
{
client[i].fd = -1;
}
while (1)
{
nready = poll(client, maxi+1, -1);
if (client[0].revents & POLLIN)
{
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 = 1; i < OPEN_MAX; ++i)
{
if (client[i].fd < 0)
{
client[i].fd = connfd;
break;
}
}
if (OPEN_MAX == i)
{
perr_exit("用户连接量过大");
}
client[i].events = POLLIN;
if (i > maxi)
{
maxi = i;
}
if (--nready <= 0)
{
continue;
}
}
for (i = 1; i <= maxi; ++i)
{
sockfd = client[i].fd;
if (sockfd < 0)
{
continue;
}
if (client[i].revents & POLLIN)
{
n = Read(sockfd, buf, BUFSIZ);
if (n < 0)
{
if (errno == ECONNRESET)
{
printf("client[%d] aborted connection\n", i);
Close(sockfd);
client[i].fd = -1;
}
else
{
perr_exit("read error");
}
}
else if (0 == n)
{
printf("client[%d] closed connection\n", i);
Close(sockfd);
client[i].fd = -1;
}
else
{
for (j = 0; j < n; j++)
{
buf[j] = toupper(buf[j]);
}
Write(sockfd, buf, n);
}
if (--nready <= 0)
{
break;
}
}
}
}
Close(listenfd);
return 0;
}
wrap.c
#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;
}