Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2000:
[Freeciv-Dev] Re: Freeciv networking
Home

[Freeciv-Dev] Re: Freeciv networking

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: 蔡恆華 <iquin@xxxxxxxxxx>
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: Freeciv networking
From: akemnade@xxxxxxxxxxx (Andreas Kemnade)
Date: Thu, 13 Jul 2000 12:19:07 +0200 (CEST)

=?BIG5?B?vbKr7bXY
?= writes:
 > > But i have several reasons against it:
 > > 1) slow (one more layer)
 > True. However, this is not the bottleneck.
 > Not much if compared to goto handling.

Perhaps some or most functions can be simple one line inlines so it
would not be much slower.

 > > 2) you still have to code the network suport for the other program
 > Much like client/gui-*
 > > 3) prone to problems
 > IIRC, we caused some platform to fail when changing something
 > about non-blocking a while ago.
 > > 4) difficult to sync both programs
 > Do you mean runtime or source code?
 > 
 > The main advantage would be modularity.
 > And the earlier it is started the better.
 > 
 > BTW, I didn't find anything about win32 problem in gnupg.
 > Can anyone help?
 > 
I don't know anything about the win32 problem in gnupg. But I have
some clues:

On win32 there is a difference between fopen(filename,"r"/"w") and
fopen(filename,"rb"/"wb"). Some files, I considered to be text files,
failed to read when opening without b.
Perhaps stdin/stdout is "opened" as a text file and so there are the
same problems.

You can't use select to test for input on stdin. You can define
SOCKET_ZERO_ISNT_STDIN but I didn't get that working on win32.

The way I use in sniff_packets is quite ugly,
so we have also to make a more portable checking for stdin input.
The big problem is that you cannot easily separate the checking for
network input from the code for stdin input. 

I hope someone has a better solution than my code below
Does anyone know how the cygwin.dll solves that problem?


int sniff_packets(void)
{
  int i;
  int max_desc;
  fd_set readfs, exceptfs;
  struct timeval tv;
  static int year;
#ifdef SOCKET_ZERO_ISNT_STDIN
  char buf[BUF_SIZE+1];
  char *bufptr = buf;
#ifdef WIN32
  HANDLE stdinh=GetStdHandle(STD_INPUT_HANDLE);
  
SetConsoleMode(stdinh,ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT);
#endif
#endif
 
  if(year!=game.year) {
    if (server_state == RUN_GAME_STATE) year=game.year;
  }
  if (!game.timeout)
    game.turn_start = time(NULL);
 
  while(1) {
    con_prompt_on();            /* accepting new input */
 
    if(force_end_of_sniff) {
      force_end_of_sniff=0;
      con_prompt_off();
      return 2;
    }
 
    tv.tv_sec=1;
    tv.tv_usec=0;
 
    MY_FD_ZERO(&readfs);
    MY_FD_ZERO(&exceptfs);
#ifndef SOCKET_ZERO_ISNT_STDIN
    FD_SET(0, &readfs);
#endif
    FD_SET(sock, &readfs);
    max_desc=sock;
 
    for(i=0; i<MAX_NUM_CONNECTIONS; i++) {
      if(connections[i].used) {
        FD_SET(connections[i].sock, &readfs);
        FD_SET(connections[i].sock, &exceptfs);
        max_desc=MAX(connections[i].sock, max_desc);                            
      }
    }
    con_prompt_off();           /* output doesn't generate a new prompt */
#ifdef WIN32
    if (WaitForSingleObject(stdinh,1)==WAIT_OBJECT_0)
      {
       int didget;
       int inpevents;
       char buf[BUF_SIZE+1];
       /*      ResetEvent(stdinh); */
       GetNumberOfConsoleInputEvents(stdinh,&inpevents);
       if (inpevents>1)
         {
           ReadFile(stdinh,buf,BUF_SIZE,&didget,NULL);
           printf("stdin: %d\n",didget);
           if (didget>0)
             {
               *(buf+didget)='\0';
               con_prompt_enter();     /* will need a new prompt, regardless */
               handle_stdin_input((struct player *)NULL, buf);
             }
         }
      }
#endif
    if(select(max_desc+1, &readfs, NULL, &exceptfs, &tv)==0) { /* timeout */
      send_server_info_to_metaserver(0,0);
      if((game.timeout)
        && (time(NULL)>game.turn_start + game.timeout)
        && (server_state == RUN_GAME_STATE)){
        con_prompt_off();
        return 0;
      }
#ifdef SOCKET_ZERO_ISNT_STDIN
#ifndef WIN32
    if (feof(stdin))
#endif
#endif                                                                          
      continue;
    }
    if (!game.timeout)
      game.turn_start = time(NULL);
 
    if(FD_ISSET(sock, &readfs)) {            /* new players connects */
      freelog(LOG_VERBOSE, "got new connection");
      if(server_accept_connection(sock)==-1)
        freelog(LOG_NORMAL, "failed accepting connection");
    }
    for(i=0; i<MAX_NUM_CONNECTIONS; i++)   /* check for freaky players */
      if(connections[i].used && FD_ISSET(connections[i].sock, &exceptfs)) {
        freelog(LOG_VERBOSE, "cut freaky player");
        close_socket_callback(&connections[i]);
    }
#ifndef SOCKET_ZERO_ISNT_STDIN
    if(FD_ISSET(0, &readfs)) {    /* input from server operator */
      int didget;
      char buf[BUF_SIZE+1];
 
      if((didget=read(0, buf, BUF_SIZE))==-1) {
        freelog(LOG_FATAL, "read from stdin failed");
        exit(1);
      }
      *(buf+didget)='\0';
      con_prompt_enter();       /* will need a new prompt, regardless */
      handle_stdin_input((struct player *)NULL, buf);
    }
#else
#ifndef WIN32
    if(!feof(stdin)) {    /* input from server operator */
      /* fetch chars until \n or run out of space in buffer */
      while ((*bufptr=fgetc(stdin)) != EOF) {
          if (*bufptr == '\n') *bufptr = '\0';
          if (*bufptr == '\0') {
              bufptr = buf;
              con_prompt_enter(); /* will need a new prompt, regardless */
              handle_stdin_input((struct player *)NULL, buf);
              break;
          }
          if ((bufptr-buf) <= BUF_SIZE) bufptr++; /* prevent overrun */
      }
    }
#endif
#endif                                                                          
  
Andreas Kemnade



[Prev in Thread] Current Thread [Next in Thread]