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