-4

我正在制作一个带有注册登录系统的服务器聊天应用程序。在运行客户端代码时:我首先选择注册,然后在成功注册后,客户端代码提示我登录。然后我登录,它工作正常。我已经在客户端代码中的 if else 块中实现了这两件事。在此之后,我正在做一些事情,我遇到了我的 C 生活中最有吸引力的错误之一。这是我的源代码,我在其中标记了错误区域(在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)不能保证工作,因为允许实现将部分行删除到标准输出(部分意味着不终止\n)。为了安全(便携)方面,始终使用 . 终止写入标准输出的行\n。见 C99 7.19.2 第 2 段:

文本流是组成行的有序字符序列,每行由零个或多个字符加上一个终止换行符组成。最后一行是否需要终止换行符是实现定义的。[...]

于 2012-04-15T18:46:09.800 回答