Newsgroup: it.comp.programmare.win32
Titolo: Winsock e problemi in C.

Salve a tutti, sto scrivendo un piccolo serverino tcp che a fronte di
una richiesta da un client legge una riga da un file e la invia sullo 
stram appena aperto, poi si rimette in ascolto e quando arriva un' altra 
richiesta da un altro client legge un altra riga e la invia....
Mi sembrava fosse tutto corretto, ma invece...
non funziona, o meglio, funziona al primo ciclo, ma poi alla successiva 
accept() va in errore.
Secondo voi, dov'e' che sbaglio ?
Il codice e' questo:
/* --- The following code comes from 
c:\programmi\lcc\lib\wizard\textmode.tpl. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock.h>
#define CANT_FORK "Unable to handle your request right now...\n"
void Usage(char *programName)
{
         fprintf(stderr,"%s usage:\n",programName);
         /* Modify here to add your usage message when the program is
          * called without arguments */
}
/* returns the index of the first argument that is not an option; i.e.
    does not start with a dash or a slash
*/
void HandleOptions()
{
   int i,nret;
   SOCKET server,client;
   SOCKADDR_IN addr;
   char line[1700], k;
   char line2[1700];
   FILE *fp;
    WORD            wVersionRequested = MAKEWORD(1, 1);
    WSADATA         wsaData;
  WSAStartup(wVersionRequested, &wsaData);
   addr.sin_family=AF_INET;
   addr.sin_port=htons(5120);
   addr.sin_addr.s_addr=htonl(INADDR_ANY);
   server=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
   if( server==INVALID_SOCKET) {
     perror("socket");
     exit(-1);
   }
   if(bind(server, (LPSOCKADDR) &addr, sizeof(struct sockaddr))<0)
   {
     perror("bind");
    WSACleanup();
     exit(-1);
   }
   listen(server, 0);
   for(;;) {
     i=sizeof(struct sockaddr);
     fp = fopen("c:\\temp\\debug.5","r");
     //fp = fopen("/win98/temp/debug.5","r");
     while (1) {
     client=accept(server, (struct sockaddr *)&addr, &i);
         switch (WSAGetLastError()){
                 case WSANOTINITIALISED:
                 printf(" WSANOTINITIALISED \n");
                 break;
                 case WSAENETDOWN        :
                 printf(" WSAENETDOWN     \n");
                 break;
                 case WSAEFAULT  :
                 printf(" WSAEFAULT       \n");
                 break;
                 case WSAEINTR   :
                 printf(" WSAEINTR        \n");
                 break;
                 case WSAEINPROGRESS     :
                 printf(" WSAEINPROGRESS  \n");
                 break;
                 case WSAEINVAL  :
                 printf(" WSAEINVAL       \n");
                 break;
                 case WSAEMFILE  :
                 printf(" WSAEMFILE       \n");
                 break;
                 case WSAENOBUFS :
                 printf(" WSAENOBUFS      \n");
                 break;
                 case WSAENOTSOCK        :
                 printf(" WSAENOTSOCK     \n");
                 break;
                 case WSAEOPNOTSUPP      :
                 printf(" WSAEOPNOTSUPP   \n");
                 break;
                 case WSAEWOULDBLOCK     :
                 printf(" WSAEWOULDBLOCK \n");
                 break;
                 default:
                 printf("otherwise \n");
         }
     if(client>0) {
         nret = recv(client, &k, 1,0);
         if (nret !=1) exit(-1);
         for(i=0;i<sizeof(line)-1&&k!='\n';i++) {
           line[i]=k;
           if(recv(client, &k, 1,0)!=1) exit(-1);
         }
         line[i]=0;
fprintf(stderr,"%s-",line);
         if (strcmp(line,"close")==0){
            fclose(fp);
            shutdown(client, 2);
            closesocket(client);
            exit(-1);
         }
         memset(line2,'\x0',strlen(line));
         // while (!feof(fp))
         fgets(line2, sizeof(line2), fp);
         nret = send(client,line2, strlen(line2),0);
              /* write(client, "\n", 1);*/
       shutdown(client, 2);
       closesocket(client);
       }
       }
      exit(-1);
     }
}
int main(int argc,char *argv[])
{
         HandleOptions();
         return 0;
}

 accept() va in errore.
Così a naso controlla la validità dell'handle del socket.
Magari non gestisci l'handle sul disconnect (lo vede come non utilizzabile).

"Rob" <fhc...@tinPUNTO.it> ha scritto nel messaggio
news:bnxy9.2539$Bs5....@news1.tin.it...

Così dovrebbe andare:
Chiama la WSAAsyncSelect con i parametri FD_ACCEPT|FD_READ|FD_CLOSE
Poi sul FD_CLOSE fai un closesocket.

 Poi sul FD_CLOSE fai un closesocket.
L' idea in se mi sembra ottima, ma non volevo complicarmi la vita in
questo modo. Magari sara' da utilizzare nel codice definitivo, ma per
quello che deve fare questo serverino, volevo usare proprio due righe.
Il prototipo che ho postato e' perfettamente funzionante in linux e sono
due righe.
Ho trovato degli esempi per la WSAAsyncSelect, ma mi sembra piu'
articolata come gestione. Diciamo che la tengo come soluzione di ripiego
:)
Grazie cmq.
Pigi

 Secondo voi, dov'e' che sbaglio ?
Non incollo tutto il codice che è tanto...