Linux下的单进程多用户TCP服务器,采用select方法实现。
-
-
-
-
-
-
-
-
-
-
-
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
#define PORT 1234 //服务器端口
-
#define BACKLOG 5 //listen队列中等待的连接数
-
#define MAXDATASIZE 1024 //缓冲区大小
-
-
typedef struct _CLIENT
-
{
-
int fd;
-
char name[20];
-
struct sockaddr_in addr;
-
char data[MAXDATASIZE];
-
} CLIENT;
-
-
void process_client(CLIENT * client, char *recvbuf, int len);
-
-
-
-
-
-
-
-
-
-
-
void main(int argc ,char **argv)
-
{
-
int i, maxi, maxfd, sockfd;
-
int nready;
-
ssize_t n;
-
fd_set rset, allset;
-
int listenfd, connectfd;
-
struct sockaddr_in server;
-
-
CLIENT client[FD_SETSIZE];
-
char recvbuf[MAXDATASIZE];
-
int sin_size;
-
-
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
-
{
-
perror("Creating socket failed.");
-
exit(1);
-
}
-
-
int opt = SO_REUSEADDR;
-
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
-
-
bzero(&server, sizeof(server));
-
server.sin_family = AF_INET;
-
server.sin_port = htons(PORT);
-
server.sin_addr.s_addr = htonl(INADDR_ANY);
-
-
if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
-
{
-
perror("Bind error.");
-
exit(1);
-
}
-
-
if (listen(listenfd, BACKLOG) == -1)
-
{
-
perror("listen() error\n");
-
exit(1);
-
}
-
-
-
maxfd = listenfd;
-
maxi = -1;
-
for (i = 0; i < FD_SETSIZE; i++)
-
{
-
client[i].fd = -1;
-
}
-
FD_ZERO(&allset);
-
FD_SET(listenfd, &allset);
-
-
while (1)
-
{
-
struct sockaddr_in addr;
-
rset = allset;
-
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
-
printf("Select() break and the return num is %d. \n", nready);
-
-
if (FD_ISSET(listenfd, &rset))
-
{
-
printf("Accept a connection.\n");
-
-
sin_size = sizeof(struct sockaddr_in);
-
if ((connectfd =
-
accept(listenfd, (struct sockaddr *)&addr, (socklen_t *) & sin_size)) == -1)
-
{
-
perror("Accept() error\n");
-
continue;
-
}
-
-
-
for (i = 0; i < FD_SETSIZE; i++)
-
{
-
if (client[i].fd < 0)
-
{
-
char buffer[20];
-
client[i].fd = connectfd;
-
memset(buffer, '0', sizeof(buffer));
-
sprintf(buffer, "Client[%.2d]", i);
-
memcpy(client[i].name, buffer, strlen(buffer));
-
client[i].addr = addr;
-
memset(buffer, '0', sizeof(buffer));
-
sprintf(buffer, "Only For Test!");
-
memcpy(client[i].data, buffer, strlen(buffer));
-
printf("You got a connection from %s:%d.\n", inet_ntoa(client[i].addr.sin_addr),ntohs(client[i].addr.sin_port));
-
printf("Add a new connection:%s\n",client[i].name);
-
break;
-
}
-
}
-
-
if (i == FD_SETSIZE)
-
printf("Too many clients\n");
-
FD_SET(connectfd, &allset);
-
if (connectfd > maxfd)
-
maxfd = connectfd;
-
if (i > maxi)
-
maxi = i;
-
if (--nready <= 0)
-
continue;
-
}
-
-
for (i = 0; i <= maxi; i++)
-
{
-
if ((sockfd = client[i].fd) < 0)
-
continue;
-
-
if (FD_ISSET(sockfd, &rset))
-
{
-
printf("Receive from connect fd[%d].\n", i);
-
if ((n = recv(sockfd, recvbuf, MAXDATASIZE, 0)) == 0)
-
{
-
close(sockfd);
-
printf("%s closed. User's data: %s\n", client[i].name, client[i].data);
-
FD_CLR(sockfd, &allset);
-
client[i].fd = -1;
-
}
-
else
-
process_client(&client[i], recvbuf, n);
-
if (--nready <= 0)
-
break;
-
}
-
}
-
}
-
close(listenfd);
-
}
-
-
-
-
-
-
-
-
-
-
-
void process_client(CLIENT * client, char *recvbuf, int len)
-
{
-
char sendbuf[MAXDATASIZE];
-
int i;
-
-
printf("Received client( %s ) message: %s\n", client->name, recvbuf);
-
-
for (i = 0; i < len - 1; i++)
-
{
-
sendbuf[i] = recvbuf[len - i - 2];
-
}
-
-
sendbuf[len - 1] = '\0';
-
-
send(client->fd, sendbuf, strlen(sendbuf), 0);
-
}
测试结果:
阅读(679) | 评论(0) | 转发(0) |