Problemas com scanf

1. Problemas com scanf

Felipe
f0x9

(usa Ubuntu)

Enviado em 27/11/2011 - 19:06h

To fazendo uma aplicação cliente/servidor na linguaem C pelo linux para um trabalho de faculdade.

Tenho que fazer varios comandos que o cliente envia para o servidor e depois recebe uma resposta.

O que eu não to conseguindo fazer é o shutdown.

O cliente envia o comando shutdown para o servidor, e todos clientes que estão autenticados são desligados.

O problema é que enquanto o cliente está no scanf, ele não faz nada enquanto o usuário digite enter, então não tem como um cliente saber se outro enviu "shutdown"...

Não teria algum comando que "cancele" o scanf ou algo parecido?


  


2. Re: Problemas com scanf

Enzo de Brito Ferber
EnzoFerber

(usa FreeBSD)

Enviado em 28/11/2011 - 08:12h

Olá, bom dia.

Não entendi muito bem sua dúvida. Você precisa que todos os clientes fiquem sem usar o scanf() se algum deles enviar 'shutdown' pro servidor ?




3. Problemas com scanf

Felipe
f0x9

(usa Ubuntu)

Enviado em 28/11/2011 - 13:58h

Isso mesmo.
Mas eu fiz de um jeito aqui com threads. Não sei se essa era a melhor pratica pra resvolver isso, mas deu certo.
À noite eu posto o codigo fonte.

obrigado


4. Re: Problemas com scanf

Enzo de Brito Ferber
EnzoFerber

(usa FreeBSD)

Enviado em 28/11/2011 - 17:30h

É, com POSIX threads e com um sistema de códigos entre cliente/servidor você faz isso tranquilo.

Mais se não quiser complicar, faz um sistema que o servidor manda um código pro cliente, e esse código libere a entrada de dados.

Algo como:


SE(ninguem entrou com shudown) {
envia para todos os clientes liberação de entrada de dados
}

Logicamente, essa abordagem tem uma falha de que se em um momento N, todos os usuários entrarem com dados, e um desses dados for um shutdown, os outros usuários irão ficar sem feedback.

Mas é uma abordagem BEM mais simples que usar PThreads! ;)

Atenciosamente,
Enzo Ferber
[]'s


5. Re: Problemas com scanf

Reginaldo de Matias
saitam

(usa Slackware)

Enviado em 28/11/2011 - 20:09h

f0x9 escreveu:

Isso mesmo.
Mas eu fiz de um jeito aqui com threads. Não sei se essa era a melhor pratica pra resvolver isso, mas deu certo.
À noite eu posto o codigo fonte.

obrigado


Aguardamos o código fonte da sua aplicação cliente/servidor


6. Re: Problemas com scanf

Felipe
f0x9

(usa Ubuntu)

Enviado em 28/11/2011 - 23:04h

compilar e rodar cliente:
cc cliente.c -o cliente -lpthread
./cliente 127.0.0.1 5000

compilar e rodar servidor:
cc servidor.c -o servidor
./servidor 5000



obs:
127.0.0.1 é o IP do servidor
5000 é a porta que será utilizada



cliente.c
//DESENVOLVIDO POR FELIPE ALMEIDA DOS SANTOS
#include "local.h"
#include <pthread.h>
#include <signal.h>

char usuario[30], senha[30];

void strsplit(char buffer[MAX_SIZE_BUFFER], char usuario[30], char senha[30], char comando[30], char req[30]);

void strsplit(char buffer[MAX_SIZE_BUFFER], char usuario[30], char senha[30], char comando[30], char req[30]) {
char temp[MAX_SIZE_BUFFER];
strcpy(temp, usuario);
strcat(temp, "|");
strcat(temp, senha);
strcat(temp, "|");
strcat(temp, comando);
strcat(temp, "|");
strcat(temp, req);
strcpy(buffer, temp);
}



int main(int argc, char *argv[]) {
struct sockaddr_in servidor;
char buffer[MAX_SIZE_BUFFER];
char comando[30], *req;
int socket_servidor, bytes_enviados, bytes_recebidos;
int tamanho_servidor = sizeof(servidor);
socket_servidor = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servidor, sizeof(servidor));
servidor.sin_family = AF_INET;
servidor.sin_port = htons(atoi(argv[2]));
servidor.sin_addr.s_addr = inet_addr(argv[1]);
pthread_t threadSolicitaComando;
pthread_t threadRecebeDados;

void envia(char req[30]) {
if (strcmp(req, "login") == 0) {
printf("Usuário: ");
scanf("%s", usuario);
printf("Senha: ");
scanf("%s", senha);
}

strsplit(buffer, usuario, senha, comando, req);
bytes_enviados = sendto(socket_servidor, buffer, MAX_SIZE_BUFFER, 0, (struct sockaddr *)&servidor, sizeof(servidor));

}

envia("login");

void* filho2 () {
while (1) {
bytes_recebidos = recvfrom(socket_servidor, buffer,MAX_SIZE_BUFFER, 0, (struct sockaddr *)&servidor, &tamanho_servidor);
if (strcmp(buffer, "225") == 0) {
printf("Erro: Usuário ou senha incorreta.\n");
envia("login");
} else {
if (strcmp(buffer, "shutdown") != 0) {
printf("%s", buffer);
}
}
if (strcmp(buffer, "shutdown") == 0) {
pthread_cancel(threadSolicitaComando);
}
}
}

void* filho () {

while (strcmp(comando, "exit") != 0) {

if (strcmp(buffer, "shutdown") != 0) {
int achou = 0;
printf("> ");
scanf("%s", comando);

if ((strcmp(comando, "exit") != 0)) {

if (strcmp(comando, "clear") == 0) {
achou = 1;
system("clear");
}

if (strcmp(comando, "logout") == 0) {
achou = 1;
printf("Logout efetuado.\n");
envia("login");
}

if (!achou) {
envia("comando");
}
} else {
strcpy(buffer, "exit");
}
}
}
}

pthread_create(&threadSolicitaComando,NULL,&filho,NULL);
pthread_create(&threadRecebeDados,NULL,&filho2,NULL);

while (strcmp(buffer, "shutdown") != 0) {
if(strcmp(buffer, "exit") == 0) {
break;
}
}

if (strcmp(buffer, "shutdown") != 0) {
printf("\nEncerrando aplicação ...\n");
} else {

printf("\nO servidor foi desligado, encerrando ...\n");
}

close(socket_servidor);
return 0;
}




servidor.c
//DESENVOLVIDO POR FELIPE ALMEIDA DOS SANTOS
#include "local.h"
#include <time.h>
#include <unistd.h>
#include <sys/utsname.h>
#define NOME_ARQUIVO "passwd.txt"

typedef struct usr {
char usuario[30];
char senha[30];
int status;
}usr;

usr user[100];

void erro(char buffer[MAX_SIZE_BUFFER]);
void carregaUsuarios();
void date(char buffer[MAX_SIZE_BUFFER]);
void hostname(char buffer[MAX_SIZE_BUFFER]);
int logIn(char *usuario, char *senha);
void logout();
void Shutdown();
void getSO(char buffer[MAX_SIZE_BUFFER]);
void creditos(char buffer[MAX_SIZE_BUFFER]);
void whoami(char buffer[MAX_SIZE_BUFFER]);
void who();
void adduser();
void deluser();
void backuser();
void blockuser();

void executaComando(char buffer[MAX_SIZE_BUFFER]) {
char *comando, *argumentos;
int existe = 0;
comando = strtok(buffer, " ");
argumentos = strtok(NULL, "{TEXTO}");

if (strcmp(comando, "whoami") == 0) {
existe = 1;
whoami(comando);
}

if (strcmp(comando, "uname") == 0) {
existe = 1;
getSO(comando);
}

if (strcmp(comando, "creditos") == 0) {
existe = 1;
creditos(comando);
}

if (strcmp(comando, "date") == 0) {
existe = 1;
date(comando);
}

if (strcmp(comando, "hostname") == 0) {
existe = 1;
hostname(comando);
}

if (existe == 0 && strcmp(buffer, "exit") != 0) {
erro(comando);
}
}

void carregaUsuarios() {
int cont = 0, i = 0;
FILE *arq;

arq = fopen(NOME_ARQUIVO, "rt");
printf("Carregando Usuários...");
if (arq == NULL)
printf(" Erro ao abrir o arquivo '%s'.\n\n", NOME_ARQUIVO);
else {
fscanf(arq, "%s %s %i", user[i].usuario, user[i].senha, &user[i].status);
while(!feof(arq)) {
i++;
fscanf(arq, "%s %s %i", user[i].usuario, user[i].senha, &user[i].status);
}
fclose(arq);
printf(" Concluí­do.\n\n");
}
}

void erro(char buffer[MAX_SIZE_BUFFER]) {
char temp[MAX_SIZE_BUFFER];
strcpy(temp, buffer);
strcpy(buffer, "Erro: O comando '");
strcat(buffer, temp);
strcat(buffer, "' não foi encontrado.\n");
}

void date(char buffer[MAX_SIZE_BUFFER]) {
strcpy(buffer, "Data do Sistema: ");
strcat(buffer, __DATE__);
strcat(buffer, " ");
strcat(buffer, __TIME__);
strcat(buffer, "\n");
}

void hostname(char buffer[MAX_SIZE_BUFFER]) {
char temp[MAX_SIZE_BUFFER];
gethostname(temp, 200);
strcpy(buffer, "Nome do Host: ");
strcat(buffer, temp);
strcat(buffer, "\n");
}

int logIn(char *usuario, char *senha) {
int i;
int correto = 0;
for (i = 0; i < 100; i++) {
if (strcmp(usuario, user[i].usuario) == 0) {
if (strcmp(senha, user[i].senha) == 0) {
correto = 1;
}
else {
break;
}
}
}
if (correto) {
return 1;
}
else {
return 0;
}
}

void logout() {

}

void Shutdown() {

}

void getSO(char buffer[MAX_SIZE_BUFFER]) {
struct utsname temp;
uname(&temp);
strcpy(buffer, "Sistema Operacional: ");
strcat(buffer, temp.sysname);
strcat(buffer, "\n");
}

void creditos(char buffer[MAX_SIZE_BUFFER]) {
strcpy(buffer, "Desenvolvedores:\nFabrí­cio Galego Schmitd\nFelipe Almeida dos Santos\nFelipe Pavam\nLeonardo Furlan\nNatália Cavichiolli\nPaulo de Morais\nPedro Henrique");
strcat(buffer, "\nAnálise e Desenvolvimento de Sistemas, FATEC de Americana, 2011.");
strcat(buffer, "\nSistemas Operacionais I - Professor José Luiz Zem.");
strcat(buffer, "\nShell Cliente/Servidor para Ambiente Linux utilizando Sockets.\n");
}

void whoami(char buffer[MAX_SIZE_BUFFER]) {
char temp[MAX_SIZE_BUFFER];
cuserid(temp);
strcpy(buffer, "Usuário Atual: ");
strcat(buffer, temp);
strcat(buffer, "\n");
}

void who() {

}

void adduser() {

}

void deluser() {

}

void backuser() {

}

void blockuser() {

}


int main(int argc, char *argv[]) {
carregaUsuarios();
struct sockaddr_in servidor, cliente, clientes_online[100];
char buffer[MAX_SIZE_BUFFER];
char *usuario, *senha, *comando = "0", *req, *temp;
int quantidade_clientes_online = 0, existe_cliente = 0, i;
int socket_servidor, socket_cliente, bytes_recebidos, bytes_enviados;
int tamanho_cliente = sizeof(cliente);
int tamanho_servidor = sizeof(servidor);
socket_servidor = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servidor, sizeof(servidor));
servidor.sin_family = AF_INET;
servidor.sin_port = htons(atoi(argv[1]));
servidor.sin_addr.s_addr = htonl(INADDR_ANY);
bind(socket_servidor,(struct sockaddr *)&servidor, tamanho_servidor);

while (strcmp(comando, "shutdown") != 0) {
bytes_recebidos = recvfrom(socket_servidor, buffer, MAX_SIZE_BUFFER, 0, (struct sockaddr *)&cliente,&tamanho_cliente);





printf("Servidor recebeu: %s\n", buffer);

usuario = strtok(buffer, "|");
senha = strtok(NULL,"|");
comando = strtok(NULL,"|");
req = strtok(NULL,"{TEXTO}");

if (logIn(usuario, senha)) {

existe_cliente = 0;
for(i = 0; i <= quantidade_clientes_online; i++) {
if(clientes_online[i].sin_family == cliente.sin_family &&
clientes_online[i].sin_port == cliente.sin_port &&
clientes_online[i].sin_addr.s_addr == cliente.sin_addr.s_addr) {
existe_cliente = 1;
}
}

if (!existe_cliente) {
bzero(&clientes_online[quantidade_clientes_online], sizeof(clientes_online[quantidade_clientes_online]));
clientes_online[quantidade_clientes_online].sin_family = cliente.sin_family;
clientes_online[quantidade_clientes_online].sin_port = cliente.sin_port;
clientes_online[quantidade_clientes_online].sin_addr.s_addr = cliente.sin_addr.s_addr;
quantidade_clientes_online++;
}

if (strcmp(req, "comando") == 0) {
strcpy(buffer, comando);
if (strcmp(comando, "shutdown") == 0) {
for (i = 0; i <= quantidade_clientes_online; i++) {
bytes_enviados = sendto(socket_servidor, "shutdown", MAX_SIZE_BUFFER, 0, (struct sockaddr *)&clientes_online[i], tamanho_cliente);

}
}
else
{
printf("comando = %s\n\n", comando);
executaComando(buffer);
}
}
else {
strcpy(buffer, "Login efetuado.\n");
}
}
else {
strcpy(buffer, "225");
}

if (strcmp(comando, "shutdown") != 0) {
bytes_enviados = sendto(socket_servidor, buffer, MAX_SIZE_BUFFER, 0, (struct sockaddr *)&cliente, tamanho_cliente);
}
}
close(socket_servidor);
return 0;
}




local.h
//DESENVOLVIDO POR FELIPE ALMEIDA DOS SANTOS
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>

#define MAX_SIZE_BUFFER 1000




passwd.txt
root root 1
felipe 1234564 0



download dos arquivos
http://www.megaupload.com/?d=HYTGY470








Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts