我正在使用注册登录系统制作服务器聊天应用程序。在运行客户端代码时:我首先选择注册,然后在成功注册后,客户端代码提示我登录。然后我登录,它工作正常。我在客户端代码的if else块中实现了这两个东西。在此之后,我正在做一些事情,在那里我遇到了我生命中最有吸引力的错误之一。这是我的源代码,我在其中标记了有错误的区域(在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;
}
output-显示在结束运行中使用while(1)的代码的阻塞状态,如问题
中所述答案 0 :(得分:2)
如果标准输出是终端(否则为块缓冲),因此默认情况下,标准输出的printf()
是行缓冲的,因此不打印该行。尝试:
printf("Outside here\n");
或添加
fflush(stdout);
在printf()
语句之后。
(编辑)但是,fflush(stdout)
不能保证工作,因为允许实现将部分行丢弃到stdout(部分意味着不被\n
终止)。要在安全(便携)方面,始终使用\n
终止写入stdout的行。见C99 7.19.2第2段:
文本流是由字符组成的有序字符序列 行,每行由零个或多个字符加上a组成 终止换行符。最后一行是否需要 终止换行符是实现定义的。 [...]