#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/stat.h>
typedef struct on_line *linker;
struct on_line
{
char name[100];
int connfd;
linker next;
};
#include "operate.h"
#include "refresh.h"
#include "warp.h"
#define MAXLINE 4096
#define SERV_PORT 8000
linker head = NULL;
linker tail = NULL;
fd_set all_set, ready_set;
int client[FD_SETSIZE];
int maxfd, max_client;
int tmp_client[FD_SETSIZE];
int tmp_max;
void add_new_client(int listenfd)
{
struct sockaddr_in cli;
int fd, i;
socklen_t clilen;
char str[INET_ADDRSTRLEN];
clilen = sizeof(cli);
fd = Accept(listenfd, (struct sockaddr *)&cli, &clilen); /*have not deal the error*/
printf("new client from %s at port %d\n",
inet_ntop(PF_INET, &cli.sin_addr, str, sizeof(str)),
ntohs(cli.sin_port));
FD_SET(fd, &all_set);
if(fd>maxfd)
maxfd = fd; /*update the maxfd*/
for(i=0; i<FD_SETSIZE; i++)
{
if(tmp_client[i] == -1)
break;
}
tmp_client[i] = fd; /*add the new fd in the tmp_client[]*/
if(i>tmp_max)
tmp_max = i; /*update the tmp_max*/
}
void server_client()
{
int i, j, n, m, fd;
char buf[MAXLINE];
char aim[20];
char *p;
FILE *fp;
linker tmp;
int test;
struct stat mess;
for(i=0; i<=tmp_max; i++)
{
if((fd = tmp_client[i]) == -1) continue;
if(!FD_ISSET(fd, &ready_set)) continue;
n = Read(fd, buf, MAXLINE);
if(n > 0)
{
// printf("%s\n", buf);
if(!strncmp("Enrol", buf, 5)) /*the is login*/
{
p = buf;
while(*p != ' ')
p++;
p++;
user_reg(p, fd);
}else
if(!strncmp("Login", buf, 5)) /*the is enrol*/
{
p = buf;
while(*p != ' ')
p++;
p++;
test = user_entry(p, fd);
// printf("entry: %d, %d\n", test, fd);
}else
{
printf("enrol or login error\n");
Write(fd, "error\n", 6);
FD_CLR(fd, &ready_set);
continue;
}
}else
{
Close(fd);
FD_CLR(fd, &ready_set);
FD_CLR(fd, &all_set);
for(j=0; j<=tmp_max; j++)
{
if(tmp_client[j] == fd)
{
tmp_client[j] = -1;
break;
}
}
continue;
}
}
stat("message_record", &mess);
n = (int)(mess.st_size);
// printf("the file size: %d\n", n);
if(n < 30000)
fp = fopen("message_record", "a");
else
fp = fopen("message_record", "w");
for(i=0; i<=max_client; i++)
{
if((fd = client[i]) == -1) continue;
if(!FD_ISSET(fd, &ready_set)) continue;
n = Read(fd, buf, MAXLINE);
buf[n+1] = '\0';
if(n > 0)
{
fputs(buf, fp);
// printf("%s, %d, %d\n", buf, n, fd); /*because read the fd can get all character*/
if(!strncmp("message&all&", buf, 12))
{
for(j=0; j<=max_client; j++)
{
if(client[j] == -1)
continue;
Write(client[j], buf, n);
}
}else
if(!strncmp("message&", buf, 8))
{
j = 0;
m = 0;
while(buf[j] != '&')
j++;
j++;
while(buf[j] != '&')
{
aim[m] = buf[j];
j++;
m++;
}
aim[m] = '\0';
// printf("dialog only to %s\n", aim);
tmp = head;
if(tmp->next == NULL)
continue;
while(strcmp(tmp->next->name, aim) != 0)
{
tmp = tmp->next;
if(tmp->next == NULL)
break;
}
if(tmp->next == NULL)
continue;
Write(tmp->next->connfd, buf, n);
Write(fd, buf, n);
}else
{
// printf("%s\n", buf);
continue;
}
}else
{
// printf("client had close or error\n");
Close(fd);
FD_CLR(fd, &ready_set);
FD_CLR(fd, &all_set);
for(j=0; j<=max_client; j++)
{
if(client[j] == fd)
{
client[j] = -1;
break;
}
}
test = delete_online(fd);
// printf("delete result: %d\n", test);
if(test == 8)
break;
continue;
}
}
fclose(fp);
}
linker create_head(char *t, int fd)
{
linker p;
p = (linker)malloc(sizeof(*p));
strcpy(p->name, t);
p->connfd = fd;
p->next = NULL;
return p;
}
int main(int argc, char *argv[])
{
struct sockaddr_in serv;
int listenfd;
int i, nready;
head = tail = create_head("head", -1);
bzero(&serv, sizeof(serv));
serv.sin_family = PF_INET;
serv.sin_addr.s_addr = htonl(INADDR_ANY);
serv.sin_port = htons(SERV_PORT);
listenfd = Socket(PF_INET, SOCK_STREAM, 0);
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); /*often open your book*/
Bind(listenfd, (struct sockaddr *)&serv, sizeof(serv));
Listen(listenfd, 1024);
printf("server is working...\n");
FD_ZERO(&all_set);
FD_SET(listenfd, &all_set);
maxfd = listenfd;
for(i=0; i<FD_SETSIZE; i++)
{
client[i] = -1;
tmp_client[i] = -1;
}
max_client = -1;
tmp_max = -1;
while(1)
{
ready_set = all_set;
nready = select(maxfd+1, &ready_set, NULL, NULL, NULL);
if(nready < 0)
{
perror("select error");
continue;
}
if(FD_ISSET(listenfd, &ready_set))
{
add_new_client(listenfd);
nready--;
}
if(nready != 0)
server_client();
}
tail = head;
while(tail->next != NULL)
{
tail = tail->next;
free(head);
head = tail;
}
free(tail);
return 0;
}
评论0