www.pudn.com > ro4fserver.rar > core.c


#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include "core.h" 
 
int rfifo_size=32768; 
int wfifo_size=32768; 
 
int timer_data_max,timer_data_num; 
fd_set readfds; 
int fd_max; 
void (*term_func)(void)=NULL; 
 
unsigned int gettick(void) 
{ 
  struct timeval tval; 
  gettimeofday(&tval,NULL); 
  return tval.tv_sec*1000+tval.tv_usec/1000; 
} 
 
void sig_proc(int sn) 
{ 
  int i; 
  switch(sn){ 
  case SIGINT: 
  case SIGTERM: 
    if(term_func) 
      term_func(); 
    for(i=0;ieof); 
  if(session[fd]->eof) 
    return -1; 
len=read(fd,session[fd]->rdata+session[fd]->rdata_size,RFIFOSPACE(fd)); 
 
  //{ int i; printf("recv %d : ",fd); for(i=0;i0){ 
    session[fd]->rdata_size+=len; 
  } else if(len<=0){ 
    printf("set eof :%d\n",fd); 
    session[fd]->eof=1; 
  } 
  return 0; 
} 
 
int send_from_fifo(int fd) 
{ 
  int len; 
 
  //printf("send_from_fifo : %d\n",fd); 
  if(session[fd]->eof) 
    return -1; 
 
  len=write(fd,session[fd]->wdata,session[fd]->wdata_size); 
  //{ int i; printf("send %d : ",fd);  for(i=0;iwdata[i]); } printf("\n");} 
  if(len>0){ 
    if(lenwdata_size){ 
      memmove(session[fd]->wdata,session[fd]->wdata+len,session[fd]->wdata_size-len); 
      session[fd]->wdata_size-=len; 
    } else { 
      session[fd]->wdata_size=0; 
    } 
  } else { 
    printf("set eof :%d\n",fd); 
    session[fd]->eof=1; 
  } 
 
  return 0; 
} 
 
int null_parse(int fd) 
{ 
  printf("null_parse : %d\n",fd); 
  RFIFOSKIP(fd,RFIFOREST(fd)); 
  return 0; 
} 
 
int (*default_func_parse)(int) = null_parse; 
 
int connect_client(int listen_fd) 
{ 
  int fd; 
  struct sockaddr_in client_address; 
  int len; 
  int result; 
 
  //printf("connect_client : %d\n",listen_fd); 
 
  len=sizeof(client_address); 
 
  fd=accept(listen_fd,(struct sockaddr*)&client_address,&len); 
  if(fd_max<=fd) fd_max=fd+1; 
  result = fcntl(fd, F_SETFL, O_NONBLOCK); 
  setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,NULL,0); 
#ifdef SO_REUSEPORT 
  setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,NULL,0); 
#endif 
  if(fd==-1){ 
    perror("accept"); 
  } else { 
    FD_SET(fd,&readfds); 
  } 
  result = fcntl(fd, F_SETFL, O_NONBLOCK); 
  session[fd]=malloc(sizeof(*session[fd])); 
  memset(session[fd],0,sizeof(*session[fd])); 
  session[fd]->rdata=malloc(rfifo_size); 
  session[fd]->wdata=malloc(wfifo_size); 
  session[fd]->max_rdata=rfifo_size; 
  session[fd]->max_wdata=wfifo_size; 
  session[fd]->func_recv=recv_to_fifo; 
  session[fd]->func_send=send_from_fifo; 
  session[fd]->func_parse=default_func_parse; 
  session[fd]->client_addr=client_address; 
 
  //printf("new_session : %d %d\n",fd,session[fd]->eof); 
  return fd; 
} 
 
int make_listen_port(int port) 
{ 
  struct sockaddr_in server_address; 
  int fd; 
  int result; 
 
  fd = socket( AF_INET, SOCK_STREAM, 0 ); 
  if(fd_max<=fd) fd_max=fd+1; 
  result = fcntl(fd, F_SETFL, O_NONBLOCK); 
  setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,NULL,0); 
#ifdef SO_REUSEPORT 
  setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,NULL,0); 
#endif 
 
  server_address.sin_family = AF_INET; 
  server_address.sin_addr.s_addr = htonl( INADDR_ANY ); 
  server_address.sin_port = htons(port); 
 
  result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address)); 
  if( result == -1 ) { 
    perror("bind"); 
    exit(1); 
  } 
  result = listen( fd, 5 ); 
  if( result == -1 ) { /* error */ 
    perror("listen"); 
    exit(1); 
  } 
 
  FD_SET(fd, &readfds ); 
  session[fd]=malloc(sizeof(*session[fd])); 
  memset(session[fd],0,sizeof(*session[fd])); 
  session[fd]->func_recv=connect_client; 
 
  return fd; 
} 
 
int make_connection(long ip,int port) 
{ 
  struct sockaddr_in server_address; 
  int fd; 
  int result; 
 
  fd = socket( AF_INET, SOCK_STREAM, 0 ); 
  if(fd_max<=fd) fd_max=fd+1; 
  setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,NULL,0); 
#ifdef SO_REUSEPORT 
  setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,NULL,0); 
#endif 
 
  server_address.sin_family = AF_INET; 
  server_address.sin_addr.s_addr = ip; 
  server_address.sin_port = htons(port); 
 
  result = fcntl(fd, F_SETFL, O_NONBLOCK); 
  result = connect(fd, (struct sockaddr *)(&server_address),sizeof(struct sockaddr_in)); 
 
  FD_SET(fd,&readfds); 
  session[fd]=malloc(sizeof(*session[fd])); 
  memset(session[fd],0,sizeof(*session[fd])); 
 
  session[fd]->rdata=malloc(rfifo_size); 
  session[fd]->wdata=malloc(wfifo_size); 
  session[fd]->max_rdata=rfifo_size; 
  session[fd]->max_wdata=wfifo_size; 
  session[fd]->func_recv=recv_to_fifo; 
  session[fd]->func_send=send_from_fifo; 
  session[fd]->func_parse=default_func_parse; 
 
  return fd; 
} 
 
int delete_session(int fd) 
{ 
  if(fd<0 || fd>=FD_SETSIZE) 
    return -1; 
  FD_CLR(fd,&readfds); 
  if(session[fd]){ 
    if(session[fd]->rdata) 
      free(session[fd]->rdata); 
    if(session[fd]->wdata) 
      free(session[fd]->wdata); 
    if(session[fd]->session_data) 
      free(session[fd]->session_data); 
    free(session[fd]); 
  } 
  session[fd]=NULL; 
  //printf("delete_session:%d\n",fd); 
  return 0; 
} 
 
int do_sendrecv(int next) 
{ 
  fd_set rfd,wfd; 
  struct timeval timeout; 
  int ret,i; 
 
  rfd=readfds; 
  FD_ZERO(&wfd); 
  for(i=0;iwdata_size) 
      FD_SET(i,&wfd); 
  } 
  timeout.tv_sec=next/1000; 
  timeout.tv_usec=next%1000*1000; 
  ret=select(fd_max,&rfd,&wfd,NULL,&timeout); 
  if(ret<=0) 
    return 0; 
  for(i=0;ifunc_send) 
	session[i]->func_send(i); 
    } 
    if(FD_ISSET(i,&rfd)){ 
      //printf("read:%d\n",i); 
      if(session[i]->func_recv) 
	session[i]->func_recv(i); 
    } 
  } 
  return 0; 
} 
 
int do_parsepacket(void) 
{ 
  int i; 
  for(i=0;irdata_size==0 && session[i]->eof==0) 
      continue; 
    if(session[i]->func_parse){ 
      session[i]->func_parse(i); 
      if(!session[i]) 
	continue; 
    } 
    RFIFOFLUSH(i); 
  } 
  return 0; 
} 
 
int do_timer(unsigned int tick) 
{ 
  int i,nextmin=1000; 
  for(i=0;itick-tick))<=0){ 
      if(timer_data[i]->func) 
 
	timer_data[i]->func(i,tick,timer_data[i]->id,timer_data[i]->data); 
 
 
 
   switch(timer_data[i]->type){ 
      case TIMER_ONCE_AUTODEL: 
	free(timer_data[i]); 
	timer_data[i]=NULL; 
	break; 
      case TIMER_INTERVAL: 
	timer_data[i]->tick+=timer_data[i]->interval; 
	break; 
      } 
    } else if((int)(timer_data[i]->tick-tick)tick-tick; 
    } 
  } 
  return nextmin; 
} 
 
int add_timer(unsigned int tick,int (*func)(int,unsigned int,int,int),int id,int data) 
{ 
  struct TimerData *td; 
  int i; 
 
  td=malloc(sizeof(struct TimerData)); 
  if(td==NULL){ 
    fprintf(stderr,"add_timer: malloc\n"); 
    exit(1); 
  } 
  for(i=0;i=timer_data_max){ 
    if(timer_data_max==0){ 
      timer_data_max=256; 
      timer_data=malloc(sizeof(struct TimerData*)*timer_data_max); 
    } else { 
      timer_data_max+=256; 
      timer_data=realloc(timer_data,sizeof(struct TimerData*)*timer_data_max); 
    } 
  } 
  td->tick=tick; 
  td->func=func; 
  td->id=id; 
  td->data=data; 
  td->type=TIMER_ONCE_AUTODEL; 
  td->interval=1000; 
  timer_data[i]=td; 
  if(i==timer_data_num) 
    timer_data_num++; 
  return i; 
} 
 
 
 
 
 
 
 
 
 
int delete_timer(int id) 
{ 
  //printf("delete_timer %d\n",id); 
  if(id<0 || id>=timer_data_num || timer_data[id]==NULL) 
    return -1; 
  //printf("free %d\n",id); 
  free(timer_data[id]); 
  timer_data[id]=NULL; 
  return 0; 
} 
 
#define MAX_BLF 16 
 
int (*basic_loop_func[MAX_BLF])(int); 
int basic_loop_func_num=0; 
 
int add_basic_loop_func(int (*blf)(int)) 
{ 
  if(basic_loop_func_num>=MAX_BLF) 
    return -1; 
  basic_loop_func[basic_loop_func_num++]=blf; 
  return basic_loop_func_num-1; 
} 
 
int del_basic_loop_func(int id) 
{ 
  int i; 
  if(id<0 || id>=basic_loop_func_num) 
    return -1; 
  if(id!=basic_loop_func_num-1){ 
    for(i=id;i