2016-01-05 94 views
0

當我運行服務器和客戶端時,服務器「接受()」客戶端。 [printf 1] printf(CONNECTION ACCEPTED)和之後不運行[printf 2] printf(等待登錄客戶端)。服務器只有在客戶端寫入套接字後才運行此行[login e password]爲什麼?C - app Socket,在執行read()之前不執行printf()而執行

服務器

newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 


if (newsockfd < 0) 
     error("ERROR on accept"); 

printf("\nCONNECTION ACCEPTED"); 

do{ 
printf("\nWait login from client"); /*<----why this printf not run??*/ 
bzero(buffer,256); 
d = read(newsockfd,buffer,255); 
if (d < 0) 
    error("ERROR reading from socket"); 
bzero(stringa,30); 
strcat(stringa,buffer); 

user = strtok(stringa,meno); 
password = strtok(NULL,meno); 


printf("\nUSER-> %s PASSWORD -> %s\n",user,password); 
bzero(risposta,10); 
strcat(risposta,checkByUserPass(user,password)); 
if(strcmp(risposta,"OK")==0) 
    { 
    printf("\n--------------TROVATO------------------risposta = %s---\n",risposta); 
    d = write(newsockfd,"OK",18); 




    } 
else 
    { 
    printf("\n--------------NON TROVATO IN ATTESA DI LOGIN VALIDO--------------risposta = %s---\n",risposta); 
    d = write(newsockfd,"KO",18); 





    } 

}while(strcmp(risposta,"OK")!=0); 

CLIENT

void error(char *msg) 


{ 
perror(msg); 
exit(0); 
} 
int main(int argc,char *argv[]) 
{ 
char u[20]; 
char p[10]; 
char meno[2]="-"; 
char input[10]; 
char servizio[10]; 


int sockfd,portno,n,newsockfd; 
struct sockaddr_in serv_addr;        //struct sockaddr 
struct hostent *server;        //hostent è una struttura definita su netdb.h e conterrà le 
              //informazioni sull'host, attraverso "struct hostent *gethostbyname(char *name);" 


char buffer[256]; 

    if(argc<3)          //se ci sono meno di 3 argomenti fallisce 
    { 
    fprintf(stderr,"usage %s hostname port\n",argv[0]); 
    exit(0); 
    } 

portno=atoi(argv[2]);         //il terzo argomento è il numero di porta 
sockfd=socket(AF_INET,SOCK_STREAM,0);       //apriamo connessione di tipo socket socketfd descrittore 

    if(sockfd<0) 
    { 
    error("error opening socket"); 
    } 

server=gethostbyname(argv[1]);        //che prende un nome come attributo e restituisce una puntatore a una struttura 
              //di tipo hostent contenente le informazioni dell'host 

    if(server==NULL) 
    { 
    fprintf(stderr,"error,no such host\n"); 
    exit(0); 
    } 

bzero((char*)&serv_addr,sizeof(serv_addr));      //azzero il buffer server_addr 
serv_addr.sin_family=AF_INET;        //compilo i campi 
bcopy((char*)server->h_addr,(char*)&serv_addr.sin_addr.s_addr,server->h_length); //uso void bcopy(char *s1,char *s2,int lenght) perchè server->h_addr è una stringa 
serv_addr.sin_port=htons(portno);        //compilo campi struttura server_addr 

    if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0)  //fase connect() prende 3 parametri : descrittore , indirizzo di memoria puntatore struct sockaddr, 
               //dimensione indirizzo 
    { 
    error("error connecting"); 
    } 

    bzero(buffer,256);          //azzero il buffer 
/*----------PRENDERE USER E PASSWORD----------------------------*/ 
    printf("\nCONNESSIONE AVVENUTA COL SERVER."); 
    do{ 
    printf("\nINSERIRE DATI PER IL LOGIN."); 

     sleep(1);        
    printf("\n\nEnter the user to insert : "); 
    fgets(u,100,stdin); 
    if (u[strlen(u) - 1] == '\n')  //rimuove lo /n generato dalla fgets 
    { 
    u[strlen(u) - 1] = '\0'; 
    } 


    printf("\n\nEnter the passw to insert : "); 
    scanf("%s",p); 
    strcat(u,meno); 
    strcat(u,p); 

    bzero(buffer,256); 
    strcat(buffer,u); 
    printf("@debug-Messaggio da mandare -> %s", buffer); 
    sleep(1); 
    //bzero(u,20); 
    n=write(sockfd,buffer,strlen(buffer)); 

     if(n<0) 
     { 
     error("error writing to socket"); 
     } 

     bzero(buffer,256); 
     n=read(sockfd,buffer,255); 

     if(n<0) 
     { 
     error("error reading rom socket"); 
     } 
     else 
     { 
     printf("server: %s",buffer); 
     //fputs(buffer, stdout); 
     bzero(servizio,10); 
     strcat(servizio,buffer); 
     printf("\nservizio = ---%s---",servizio); 
     } 
     if (strcmp(servizio,"OK")==0) 
     { 
     printf("\n Login accettato"); 
     getchar(); 
     } 
     else 
     { 
     printf("\n Conto non trovato"); 
     getchar(); 
     } 
    }while(strcmp(servizio,"OK")!=0); 

回答

2

在打印否則不能保證它會沒有明確的fflush顯示的文本的末尾添加\n。即:

printf("\nWait login from client\n"); 

或者:

printf("\nWait login from client"); 
fflush(stdout); 
+0

哦,謝謝,解決了。 爲什麼會發生這種情況? 何時正確使用fflush(stdout)? – volcom

+0

默認緩衝I/O。這意味着,例如,當您在流上寫入時,數據實際上將存儲在內存中的某個位置(即在緩衝區中),而不是實際寫入的。只有在某些情況下才能有效地寫入這些數據,例如:當內存已滿時。 fflush函數強制這樣的緩衝區被刷新,即,即使正常的寫入條件尚未發生,數據也會被有效寫入。點擊此鏈接瞭解更多詳情:http://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html#Buffering-Concepts – mikedu95

相關問題