【问题标题】:C - app Socket , not execute printf() before read() in do-whileC - app Socket,在 do-while 中的 read() 之前不执行 printf()
【发布时间】:2016-01-05 15:17:58
【问题描述】:

当我运行服务器和客户端时,服务器“accept()”客户端。 [printf 1] printf (CONNECTION ACCEPTED) 之后不运行第二个 [printf 2] 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);

客户

 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);

【问题讨论】:

    标签: c sockets


    【解决方案1】:

    在打印的文本末尾添加\n,否则无法保证在没有明确 fflush 的情况下显示。即:

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

    或者:

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

    【讨论】:

    • 哦,谢谢,已解决。为什么会这样?什么时候使用 fflush ( stdout ) 合适?
    • I/O 默认是缓冲的。这意味着,例如,当您在流上写入时,数据实际上将存储在内存中的某个位置(即在缓冲区中),而不是实际写入。这些数据仅在某些情况下才会有效写入,例如:当该内存已满时。 fflush 函数强制刷新这样的缓冲区,即有效地写入数据,即使在正常写入条件尚未发生时也是如此。点击此链接了解更多详情:gnu.org/software/libc/manual/html_node/…
    猜你喜欢
    • 2021-07-01
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多