- 论坛徽章:
- 0
|
一个服务器可对应多个客户端,经测试,服务器可以跟多个客户端交互,只是只能输入输出一条信息,希望大侠帮我看看,谢谢
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <time.h>
#define MAX_BUF_SIZE 1024
#define MAX_LISTEN 12
int main(int argc, char *argv[])
{
int sockfd, conn_fd;
int client_fd[MAX_LISTEN];
struct sockaddr_in my_addr, client_addr;
unsigned int backlog, port;
int sin_size;
char buf[MAX_BUF_SIZE + 1];
fd_set rfds;
struct timeval tv;
int retval, maxfd = -1;
int i;
if (argv[1])
port = atoi(argv[1]);
else
port = 8003;
if (argv[2])
backlog = atoi(argv[2]);
else
backlog = 12;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "socket error!\n");
exit(1);
}
int on = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
{
fprintf(stderr, "setsockopt failed: %s\n", strerror(errno));
exit(1);
}
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(port);
if (argv[3])
my_addr.sin_addr.s_addr = inet_addr(argv[3]);
else
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
fprintf(stderr, "bind error!\n");
exit(1);
}
if (listen(sockfd, backlog) == -1)
{
fprintf(stderr, "listen error!\n");
exit(1);
}
printf("*****wait new connection to new chat*****\n");
for (i=0; i<MAX_LISTEN; i++)
client_fd = -1;
FD_ZERO(&rfds);
maxfd = sockfd;
while (1)
{
FD_CLR(sockfd, &rfds);
FD_SET(sockfd, &rfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
if ((retval = select(maxfd + 1, &rfds, NULL, NULL, &tv)) < 0)
{
if (errno == EINTR)
{
fprintf(stdout, "closed by singal, continue...\n");
continue;
}
else if (errno == EAGAIN)
{
continue;
}
else
{
fprintf(stderr, "select error!\n");
}
}
else if (retval == 0)
{
continue;
}
fprintf(stdout, "Be ready, can chat!\n", retval);
if (FD_ISSET(sockfd, &rfds))
{
sin_size = sizeof(struct sockaddr);
conn_fd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);
if (conn_fd < 0)
{
if (errno == EINTR)
continue;
else
{
fprintf(stderr, "accept error!\n");
exit(1);
}
}
for (i=0; i<MAX_LISTEN; i++)
{
if(client_fd != -1)
continue;
client_fd = conn_fd;
FD_SET(client_fd, &rfds);
break;
}
if (maxfd < conn_fd)
maxfd = conn_fd;
printf("Add client socket connection %d to select\n", conn_fd);
}
for (i=0; i<MAX_LISTEN; i++)
{
if (client_fd == -1)
continue;
if (!FD_ISSET(client_fd, &rfds))
continue;
bzero(buf, MAX_BUF_SIZE + 1);
sin_size = recv(client_fd, buf, MAX_BUF_SIZE, 0);
if (sin_size > 1)
{
printf("receive message successfully: [%s]\ntotal %d bytes\n", buf, sin_size);
}
else
{
close(client_fd);
FD_CLR(client_fd, &rfds);
printf("del socket %d from select pipe. \n", client_fd);
client_fd = -1;
break;
}
FD_SET(0, &rfds);
if (FD_ISSET(0, &rfds))
{
bzero(buf, MAX_BUF_SIZE + 1);
fgets(buf, MAX_BUF_SIZE, stdin);
if (!strncasecmp(buf, "quit", 4))
{
printf("quit chat!\n");
break;
}
sin_size = send(client_fd, buf, strlen(buf)-1, 0);
if (sin_size > 0)
{
printf("message: %s\t send successfully, total %d bytes!\n", buf, sin_size);
}
else
{
printf("message: %s\t send failure, error code is %d, error message is %s\n",
buf, errno, strerror(errno));
}
}
}
for (i=0; i<MAX_LISTEN; i++)
{
if (maxfd < client_fd)
{
maxfd = client_fd;
}
}
printf("This cycle of select loop over, max_fd = %d\n", maxfd);
}
printf("any chat?(no -> quit)");
fflush(stdout);
bzero(buf, MAX_BUF_SIZE + 1);
fgets(buf, MAX_BUF_SIZE, stdin);
if (!strncasecmp(buf, "no", 2))
{
printf("quit chat3!\n");
}
close(sockfd);
return 0;
}
[ 本帖最后由 shenxiaocheng 于 2009-7-8 16:08 编辑 ] |
|