-4

登録ログインシステムでサーバーチャットアプリケーションを作成しています。クライアントコードの実行中:最初に登録を選択し、登録が成功した後、クライアントコードはログインを促します。それから私はログインし、それはうまくいきました。クライアントコードのifelseブロックにこれら2つのことを実装しました。この後、私は自分のCライフで最も魅力的なエラーの1つに遭遇したときに何かをしています。これが私のソースコードで、その領域をエラーでマークし(main関数の最後に)、そこで問題についても言及しています(問題のコード定義は簡単です)。
コードの後に​​出力も投稿しました。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
#define PORT "1618" //the port client will be connecting to
#define MAXDATASIZE 100 // max number of bytes we can get at once

static const int BUFFER_SIZE = 16*1024;
//get sockaddr ,IPv4 or IPv6:




void *get_in_addr(struct sockaddr *sa)
{
    if(sa->sa_family ==AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int registerYourself(int sockfd)
{   
    printf("2\n");
    char username[50], password[50],registerStatus[2];
    int return_value,choice;
    printf("You have chosen to register yourself\n");
    printf("Please enter a username and password\n");
    printf("Username:");
    scanf("%s",username);
    //printf("You entered %s\n",username);
    send(sockfd,username,sizeof(username),0); // sending username
    printf("\nPassword:");
    scanf("%s",password);    //sending password
    //printf("-- %s\n",password);
    send(sockfd,password,sizeof(password),0);           //sending password
    recv(sockfd,registerStatus,sizeof(registerStatus),0);//receiving from server that register is successful or not
    if(strcmp(registerStatus,"1")==0) //If register successful then promoting for log-in
        {
        printf("Registration successfull\n Please Log in\n");
        return_value=login(sockfd);
        return return_value;
        }
    else if(strcmp(registerStatus,"0")==0)// Asking user what to do
        {
        printf("Username already taken...Please try again with other username...\nPress:\t 1 to try again\n\t2 to quit");
        scanf("%d",&choice);
        switch(choice)
            {
            case 1:
                  send(sockfd,"1", 2, 0);
                registerYourself(sockfd);
                break;
            case 2:
                send(sockfd,"0",2,0);
                return 0;
            }           
        }
}

int login(int sockfd)
{   
    printf("3\n");
    char username[50],password[50],login_status[2];
    int choice;
    printf("You have chosen to login yourself\n");
    printf("Please enter a username and password\n");
    printf("Username:");
    scanf("%s",username);
//  printf("-- %s\n",username);
    send(sockfd,username,sizeof(username),0);
    send(sockfd,username,sizeof(username),0);//send username
    printf("\nPassword:");
    scanf("%s",password);
    //printf("-- %s\n",password);
    send(sockfd,password,sizeof(password),0);//send password
    recv(sockfd,login_status,sizeof(login_status),0); // //receiving from server that login is successful or not
    if(strcmp(login_status,"1")==0)
        {
        printf("login successfully 1\n");
        //while(1);// doing other job here
        return 1;
        }
        else if(strcmp(login_status,"0")==0)
        {
        printf("Wrong Username And/Or Password\nPress:\n__1)__To Enter Again  |  __2)__To Quit");
        scanf("%d",&choice);
        switch(choice)
            {
            case 1:
                send(sockfd,"1", 2, 0);// sending that user want to login again
                login(sockfd);
                break;
            case 2:
                send(sockfd,"0",2,0);// sending that user want to stop
                return 0;
            //TODO default case 
            }
        }
        //break;//case 2 ends
}


int main(int argc, char *argv[])
{
    char fname[50], s[INET6_ADDRSTRLEN], buf[MAXDATASIZE], username[50], password[50], registerStatus[2], login_status[2];
    int sockfd, numbytes,fp,i,rv, choice,iflogin=0;

    struct addrinfo hints, *servinfo, *p;

    if(argc != 2) 
        {
            fprintf(stderr,"usage: client hostname\n");
            exit(1);
        }

        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;

        if((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) 
        {
            fprintf(stderr,"getaddrinfo: %s\n",gai_strerror(rv));
            return 1;
        }

        //lopp through all the results and connect to the first we can
        for(p = servinfo; p != NULL; p = p->ai_next) 
        {
            if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
                perror("client: socket");
                continue;
            }

            if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1)
            {
                close(sockfd);
                perror("client: connect");
                continue;
            }
            break;
        }

        if(p ==NULL) 
        {
            fprintf(stderr,"client: failed to connect\n");
            return 2;
        }

        inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s);
        printf("client : connecting to %s\n", s);

        freeaddrinfo(servinfo); // all done with this structure





**//////////////////////////       Here problem /////////////////////////**Code is continuous just to show you that problem is here.


//////////////////////////       Here problem /////////////////////////
//////////////////////////       Here problem /////////////////////////
//////////////////////////       Here problem /////////////////////////


        printf("\n----------------Menu-------------------------\n1.Register\n2.Log in\n");
        scanf("%d",&i); //here i am asking user whether to register or login and while running i choose to register 
        int status_value;   

            if(i==1)// I am going to enter in this loop
                {
                    send(sockfd,"1", 2, 0);//sending server that user want to register - work fine
                    printf("1\n");//work fine
                    status_value = registerYourself(sockfd);//this function ask me to register ang return 1 for success which is happening when I am running this code as:
                    if(status_value == 1)
                    {
                        printf("Logged in successful inside case 1\n"); // this prints
                        iflogin = 1;
                        printf("HERE 1-----------------\n");//this prints
                        printf("HERE 1-----------------\n");//this prints
                    }
                    else    //not get in this -obvious
                    {
                        printf("Bye!!!");   
                        printf("HERE 1!!!!!!!!!!!!!\n");        
                    }
                }
            if(i==2)// also dont go in this loop - obvious
            {
                printf("Inside case 2");
                send(sockfd,"2", 2, 0); //sending server that user want to login
                //status_value = login(sockfd);
                if(status_value == 1)
                    {
                    printf("Logged in successful inside case 2\n");
                    iflogin = 1;
                    }
                else    {
                    printf("Bye!!!");           
                    }

            }

        //fflush(stdout);
        //fflush(stdin);
        //fflush(stderr);

        // now some mytic thing is happening. this is not get printed and programmed get blocked [dont get stopped] just get blocked
        //if I commented the last while(1) [in the end] loop then everything works fine
        //if I commented the last while(1) and uncomment the sleep(5) statement t'outside here get printed after 5 seconds means after the sleep statement'
        //I have also tried to flush - but this shit is not flushing
        //pls tell me what is happening
        printf("Outside here");
        printf("Outside here");
        printf("Outside here");
        //sleep(5);
        if(iflogin==1)
        {
            printf("Logged in");
        }
        else
        {
            printf("Final Bye");
        }
        while(1); //doing other job
        close(sockfd);

        return 0;
}

出力-問題で説明されているように、while(1)で実行された最後のコードのブロックされた状態を示します 出力-問題で説明されているように、while(1)で実行された最後のコードのブロックされた状態を示します

4

1 に答える 1

2

printf()標準出力が端末の場合、デフォルトで標準出力に行バッファリングされるため、行は印刷されません(それ以外の場合はブロックバッファリングされます)。試す:

printf("Outside here\n");

または追加

fflush(stdout);

printf()ステートメントの後。(編集)ただし、fflush(stdout)実装では部分的な行をstdoutにドロップすることが許可されているため(部分的な意味はで終了しない)、動作は保証されません\n。安全(ポータブル)側にするために、stdoutに書き込まれた行は常に。で終了して\nください。C99 7.19.2段落2を参照してください:

テキストストリームは、行に構成された文字の順序付けられたシーケンスであり、各行は0個以上の文字と終了する改行文字で構成されます。最後の行に終了改行文字が必要かどうかは、実装によって定義されます。[...]

于 2012-04-15T18:46:09.800 に答える