Ir para conteúdo
Fórum Script Brasil
  • 0

chat em c com gravaçao de historico


Ariel Arieiro

Pergunta

estou com dois codigos em c. o primeiro trata-se de um chat em c com manipulaçao de sockets

o segundo codigo trata de processos fork para gravar o historico das conversas no chat. 

gostaria se possivel introduzir o segundo codigo, dentro do primeiro fazendo com que ele grave as conversas do chat em um arquivo que gere automatico o relatorio de conversas, nao estou conseguindo fazer isso, sou aluno do 2 periodo de sistemas para internet

segue ai os dois codigos

CODIGO 1

CHATSERVER

 

/* charservidor 1.0
 * sistemas distribuidos IFTO  
esse servidor trabalha com um numero maximo de 20 conexões por chat
voce pode escolher entre 2 ate 20 maquinas ao mesmo tempo
a maquina que executa o servidor deve abrir um novo terminal e conectar no servidor atraves do ip na qual o servidor está alocado.
para as demais maquinas se conectarem elas devem, acessar o terminal e digitar o comando e acrescentar o ip do servidor e se conectar
vamos la: 

primeiro passo vamos compilar e executar este codigo servidor, para isso digite no terminal: gcc -o chatserv chatserv.csegundo passo rode o programa ./chatserv e escolha a porta aqui no caso sera 8080 e defina um numero maximo de conexao que sera 20 Agora servidor está rodando. Agora só basta distribuir o IP do servidor e a porta. A porta é a 8080 como especificado.para cada maquina que quiser se conectar ao servidor basta digitar  nc <ip do servidor> 8080 para o usuario utilizar um nick basta ele digitar antes de se conectar ao servidor sed -u 's/.(asteristico)/<seu nick>: &/' | nc localhost 31337

o chat esta pronto para uso
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/times.h>
#include <sys/select.h>
#include <unistd.h>

#define SERVER_BUSY "DESCULPE O SERVIDOR ESTA LOTADO, TENTE NOVAMENTE MAIS TARDE\n"

#define MAX_USERS 20
#define MSG_LEN 4096

int socket_listening ;
/* Para selecionar() */
fd_set select_set ;

int  *list_of_sockets ;

int  max_users = MAX_USERS ;

/* aqui a variavel aumenta toda vez
 * que um usuario se conecta
 * e essa variavel armazena o tamanho atual da lista*/
int  list_len = 0 ;

/* the user message */
char msg[MSG_LEN+1] ;

void show_help(char *name) {
printf("Chatservidor 1.0\n") ;
printf("by IFTO(http://portal.ifto.edu.br/)\n\n") ;
printf("[uso] %s <porta> [<maximo_usuarios>]\n", name) ;
}

/* if it's possible to insert a socket in
 * the list, this function returns 0 and
 * 1 otherwise.
 */
char insert_socket_into_list(int socket) {
    int i ;

    if ( list_len == max_users ) {
        return 1 ;
    }

    for ( i = 0; i < max_users; i++ ) {
        if ( list_of_sockets == -1 ) {
            list_of_sockets = socket ;
            list_len++ ;
            break ;
        }
    }
    return 0 ;
}

/* procura um socket na lista e 
 * fecha ele
 */
void remove_socket_from_list(int _sock) {
    int i ;

    for ( i = 0; i < max_users; i++ ) {
        if ( list_of_sockets == _sock ) {
            close(list_of_sockets) ;
            list_of_sockets = -1 ;
            list_len-- ;
            break ;
        }
    }
}

/* Recebe a mensagem de um usuário
esta mensagem estará armazenda na variavel 'msg'.
ela vai retornar 0 caso a mensagem seja enviada com sucesso 
e 1 se o cliente estiver terminado a conexao.
*/
char get_message_from_socket(int _sock) {
    int t ;

    memset(msg,0x0,MSG_LEN+1) ;
    t = recv(_sock, msg, MSG_LEN, 0 ) ;

    if ( t == 0 ) {
        remove_socket_from_list(_sock) ;
        return 1 ;
    }
    return 0 ;
}

/* 
 Depois que nós iniciarmos o servidor
  uma  mensagem e enviada ,
 Enviaremos para todos os outros aqui.
 Observe que um usuário não pode enviar uma mensagem
 Para si mesmo (list_of_sockets ! = _sock).
 */
void send_message_to_all(int _sock) {
    int i ;

    for ( i = 0; i < max_users; i++ ) {
        if ( (list_of_sockets != -1)    &&
             (list_of_sockets != _sock) &&
             (list_of_sockets != socket_listening) ) {

            send(list_of_sockets, msg, strlen(msg), 0) ;
        }
    }
}

int main(int argc, char **argv) {
    int port ;
    int t    ;

    struct sockaddr_in server ;
    struct timeval select_time ;

    if ( argc == 1 ) {
        show_help(argv[0]) ;
        return -1 ;
    }

    if ( argc > 2 ) {
        max_users = atoi(argv[2]) ;
    }

    port = atoi(argv[1]) ;

    socket_listening = socket(AF_INET, SOCK_STREAM, 0) ;

    if ( socket_listening < 0 ) {
        perror("socket") ;
        return -1 ;
    }

    server.sin_family = AF_INET ;
    server.sin_port = htons(port) ;
    server.sin_addr.s_addr = INADDR_ANY ;

    t = sizeof(struct sockaddr_in) ;
    if ( bind( socket_listening, (struct sockaddr *) &server, t ) < 0 ) {
        perror("bind") ;
        return -1 ;
    }

    if ( listen(socket_listening, 5) < 0 ) {
        perror("listen") ;
        return -1 ;
    }

    /* Crie a lista de soquetes.
      Para cada cliente, há um soquete nesta lista.
     */
    list_of_sockets = (int *) malloc( max_users * sizeof(int) ) ;
    if ( list_of_sockets == NULL ) {
        perror("malloc") ;
        return -1 ;
    }

    /* "limpa a lista". */
    for ( t = 0; t < max_users; t++ )
        list_of_sockets[t] = -1 ;

    /* Você precisará de um ctrl + c para quebrar esse loop*/
    while ( 1 ) {
        /* Recebe todas sockets e coloca
         * Fd_set struct. */
        FD_ZERO(&select_set) ;
        FD_SET(socket_listening, &select_set) ;
        for ( t = 0; list_len > 0 && t < max_users; t++ ) {
            if ( list_of_sockets[t] != -1 ) {
                FD_SET(list_of_sockets[t], &select_set) ;
            }
        }

        printf("[+] LISTANDO MAQUINAS CONECTADAS AGORA NA PORTA %d [%d/%d] ...\n", port, list_len, max_users) ;

        /* Selecione esperar 2 segundos antes
         * Retornando. */
        select_time.tv_sec = 2 ;
        select_time.tv_usec = 0 ;

        /* seleciona retornar:
         * < 0 se der erro.
         * = 0 se nao acontecer nada
         * > 0 numero de sockets no servidor
         */
        if ( (t=select(FD_SETSIZE, &select_set, NULL, NULL, &select_time)) < 0 ) {
            perror("select") ;
            return -1 ;
        }

        /* aqui ja temos algo ... */
        if ( t > 0 ) {
            /* quando listamos os socket, precisamos:
              aceitar a uma nova conexao e adicionar
             um novo socket na lista*/
            if ( FD_ISSET(socket_listening, &select_set) ) {
                int n ;

                if ( (n=accept(socket_listening, NULL, NULL)) < 0 ) {
                    perror("accept") ;
                } else if ( insert_socket_into_list(n) == 1 ) { /* server is busy */
                    send(n,SERVER_BUSY,strlen(SERVER_BUSY),0) ;
                    close(n) ;
                }
                continue ;
            } else {
                int i ;

                /* para manipular os dados de entrada */
                for ( i = 0; i < max_users; i++ ) {
                    if ( FD_ISSET(list_of_sockets, &select_set) ) {
                        if ( get_message_from_socket(list_of_sockets) == 0 ) {
                            send_message_to_all(list_of_sockets) ;
                        }
                    }
                }
            }
        }
    } /* laço while */

    return 0 ;
} /* finaliza a main*/

 

 

 

CODIGO 2

 

GRAVAR HISTORICO CONVERSA

 

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define MAX_BUF 1000
#define true !0
#define false 0

void proc_consumidor( FILE *arq_log ) {
    char buffer[MAX_BUF];
    int flag = false;
   
    // procedimento para ler todas as linhas do arquivo e imprimir no terminal
    while( !flag ) {
        fseek( arq_log, 0L, SEEK_SET ); // volta o cursor ao começo do arquivo
        while( fgets( buffer, MAX_BUF, arq_log ) != NULL ) { // le uma linha do arquivo e coloca no buffer. Retorna NULL no fim de arquivo (EOF)
            printf( "%s\n", buffer ); // imprime o buffer
            flag = true; // com esta bandeira verdadeira, termina a execucao do while, ou seja, imprime o arquivo uma unica vez
        }
    }
    exit(EXIT_SUCCESS);
}

void proc_produtor( FILE *arq_log ) {
    char *buffer2;   
    buffer2 = (char *)malloc( MAX_BUF * sizeof(char) ); // Aloca MAX_BUF caracteres e atribui a buffer2
    
    printf( "Digite uma frase: " );
    while( fgets( buffer2, MAX_BUF, stdin ) != NULL ) {
        fputs( buffer2, arq_log );
        fflush( arq_log ); // forca o descarregamento dos buffers internos para o arquivo
        printf( "Digite uma frase: " );
    }
    free(buffer2); // desaloca buffer2
    exit(EXIT_SUCCESS);
}

int main(void)
{
    pid_t pid_prod = 0;
    pid_t pid_cons = 0;
    int status;

    FILE *arq_log;
    arq_log = fopen( "teste.log", "w+"); // abre o arquivo para leitura e escrita. "w+" trunca o arquivo. Se quiser preservar usar "r+"
    if( arq_log == NULL ) {
        printf( "erro no pai ao abrir arquivo.\n" );
        exit(EXIT_FAILURE);
    }
    
    // Cria o processo filho produtor
    pid_prod = fork(); // bifurca e armazena o pid do produtor
    if ( pid_prod == 0 ) { // filho 1 - produtor
        proc_produtor( arq_log );        
    }
    
    // Cria o processo filho produtor    
    pid_cons = fork(); // bifurca e armazena o pid do consumidor
    if ( pid_cons == 0 ) { // filho 2 - consumidor
        proc_consumidor( arq_log );
    }
    
    // pai
    waitpid( pid_cons, &status, 0 ); // aguarda o processo consumidor encerrar
    waitpid( pid_prod, &status, 0 ); // aguarda o processo produtor encerrar
    fclose(arq_log);
    
    return 0;
}
 

Link para o comentário
Compartilhar em outros sites

0 respostass a esta questão

Posts Recomendados

Até agora não há respostas para essa pergunta

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...