Ich simuliere einen Chat-Dienst in C-Sprache Ich sende eine Mensage zur Server-Seite wie "U: Benutzername, Passwort; um einen Benutzer anzumelden, aber wenn ich frage, wer online ist, drucke es n-mal der Name des Benutzers), der fragt Was nicht das erwartete Verhalten ist. Jemand kann mir sagen, warumWarum meine Simulation von Chat-Dienst falschen Inhalt schreiben?
?server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <linux/stat.h>
#define FIFO_FILE "MYFIFO"
typedef struct online {
char* user;
struct online* next;
} online;
typedef struct users{
char* name;
char* password;
} users;
online* begin=NULL;
online* end=NULL;
FILE *fp;
void start_server();
void add_online(char* user);
void realocate_end();
void remove_online(char* user);
char* user_access(char* s);
void who_online();
void free_all();
int find_username(char* user);
void add_user_regist(char* user,char* password);
users* find_user_regist(char* user, char* password);
int main(int argc, char *argv[])
{
if(argc>1){
char password[50];
char password2[50];
printf("Password? ");
scanf("%s",password);
printf("Repita a password? ");
scanf("%s",password2);
if(strcmp(password,password2)!=0){
printf("Passwords diferentes!\n");
exit(1);
}
if(find_username(argv[1])){
printf("Utilizador ja existe\n");
exit(1);
}
add_user_regist(argv[1],password);
printf("Utilizador %s adicionado.\n",argv[1]);
exit(0);
}
char readbuf[250];
/* Create the FIFO if it does not exist */
umask(0);
mknod(FIFO_FILE, S_IFIFO|0666, 0);
printf("Servidor iniciado.\nEm modo de espera de mensagens\n");
while(1)
{
fp = fopen(FIFO_FILE, "r");
fgets(readbuf, 250, fp);
fclose(fp);
if(readbuf[0]=='U')
user_access(readbuf);
if(readbuf[0]=='W')
who_online();
printf("Received string: %s\n",readbuf);
}
return(0);
}
void realocate_end(){
online* tmp=begin;
while(tmp!=NULL){
if(tmp->next==NULL)
end=tmp;
tmp=tmp->next;
}
}
void remove_online(char* user){
online* tmp=begin;
char path[100];
sprintf(path,"/tmp/chatroom_%s",user);
unlink(path);
while(tmp!=NULL){
if(tmp->user==user && tmp->user == end->user){
free(end);
end=NULL;
realocate_end();
}
else if(tmp->user==user && tmp->user == begin->user){
begin=begin->next;
free(tmp);
break;
}
else if(tmp->next->user ==user){
online* tmp2 = tmp->next->next;
free(tmp->next);
tmp->next = tmp2;
realocate_end();
break;
}
tmp=tmp->next;
}
}
void add_online(char* user){
online* tmp = (online*)malloc(sizeof(online));
tmp->user = user;
tmp->next = NULL;
if(begin==NULL){
begin = tmp;
end=tmp;
}
else{
end->next=tmp;
end=end->next;
}
}
void who_online(){
online* tmp = begin;
while(tmp!=NULL){
printf("%s\n",tmp->user);
tmp=tmp->next;
}
}
void free_all(){
while(begin!=NULL){
online* tmp = begin->next;
free(begin);
begin = tmp;
}
}
int find_username(char* user){
FILE* fp;
char line[50];
fp=fopen("./regist", "r");
while(fscanf(fp,"%s",line)!=EOF){
char* name=strtok(line,",");
if(strcmp(name,user)==0){
fclose(fp);
return 1;
}
}
return 0;
}
char* user_access(char* s){
int i=0 ,begin=2;
strtok(s,":");
char* username=strtok(NULL,",");
char* password=strtok(NULL,";");
add_online(username);
}
users* find_user_regist(char* user, char* password){
FILE* fp;
char line[50];
users* tmp = (users*) malloc(sizeof(users));
fp=fopen("./regist", "r");
while(fscanf(fp,"%s",line)!=EOF){
tmp->name =strtok(line,",");
tmp->password = strtok(NULL,";");
if(strcmp(tmp->name,user)==0 && strcmp(tmp->password,password)==0){
fclose(fp);
return tmp;
}
}
fclose(fp);
return NULL;
}
void add_user_regist(char* user,char* password){
FILE* fp;
fp=fopen("./regist", "a");
if(fp==NULL)
fp=fopen("./regist", "w");
fprintf(fp,"%s,%s;\n",user,password);
fclose(fp);
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <termios.h>
#include <linux/stat.h>
#define FIFO_FILE "MYFIFO"
int main(int argc, char *argv[])
{
FILE *fp;
char user[50];
char password[50];
if(argc==1){
printf("Não escolheu utilizador\n");
exit(0);
}
sprintf(user,"%s",argv[1]);
printf("Password:\n");
scanf("%s",password);
getchar();
char mensagem[250];
if((fp = fopen(FIFO_FILE, "w")) == NULL) {
perror("fopen");
exit(1);
}
char path [100] ;
strcpy(path,".");
strcat(path,user);
umask(0);
mknod(path, S_IFIFO|0666, 0);
sprintf(mensagem,"U:%s,%s;",user,password);
fputs(mensagem, fp);
fclose(fp);
while(1){
printf("**Menu**\n1) Listar utilizadores online\n2) Mandar SMS a um utilizador\n3) Logout\n\n");
char opcao;
scanf("%c",&opcao);
char lixo=getchar();
if(opcao!='1' && opcao!='2' && opcao!='3')
continue;
if(opcao=='1'){
if((fp = fopen(FIFO_FILE, "w")) == NULL) {
perror("fopen");
exit(1);
}
sprintf(mensagem,"W:%s;",user);
fputs(mensagem, fp);
fclose(fp);
}
else if(opcao=='2'){
if((fp = fopen(FIFO_FILE, "w")) == NULL) {
perror("fopen");
exit(1);
}
memset(mensagem,0,sizeof(mensagem));
scanf("%s",mensagem);
char lixo=getchar();
fputs(mensagem, fp);
fclose(fp);
}
else if(opcao=='3'){
break;
}
}
return(0);
}
Stackoverflow-Dienst kein Debugging ist zu befreien. Verwenden Sie einen Debugger, um die Problembereiche einzugrenzen. Stellen Sie jedoch zuerst sicher, dass alle Strings ordnungsgemäß terminiert sind, und denken Sie daran, dass Pipes (die ein FIFO ist) eine * streaming * -Kommunikationsmethode ohne festgelegte Nachrichtengrenzen ist. Das bedeutet, dass ein Empfang möglicherweise weniger als eine vollständige Nachricht oder mehr empfängt, und Sie müssen eine Art Protokoll oben auf dem Stream implementieren, um Nachrichtengrenzen selbst einzuführen (z. B. mit Start/Stopp-Sequenzen oder einer Nachrichtengröße fester Länge) Header). –