Cliente – Servidor em C utilizando threads

Estou disponibilizando os fontes de um pequeno programa de cliente servidor implementado em C. Esse código utiliza threads na parte do servidor podendo controlar mais de um cliente.

Código Cliente. Para compilar utilize: gcc -lpthread -o cliente  cliente.c

/*********************************
Autor: Fernando Krein Pinheiro
Data: 04/07/2012
Linguagem: C
========= IMPORTANTE ===========
O código esta livre para usar,
citar e compartilhar desde que
mantida sua fonte e seu autor.
Obrigado.
*********************************
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <string.h>

int configuracaoCliente()
{
    /*Descritor do cliente*/
    int clienteSockfd;
    /*Estrutura do Cliente*/
    struct sockaddr_in serv_addr;
    /*Tamanho da estrutura*/
    socklen_t addrlen = sizeof (serv_addr);

    /*Socket familia TCP declarado SOCK_STREAM e criado*/
    clienteSockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (clienteSockfd < 0)
	{
	    printf("Erro no Socket\n");
		exit(1);
	}
    /*Zera a estrutura*/
    bzero((char *) & serv_addr, sizeof (serv_addr));
    /*Seta a familia*/
    serv_addr.sin_family = AF_INET;
    /*Define o IP nesse caso o localhost*/
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    /*Define a porta de conexao*/
    serv_addr.sin_port = htons(6881);
   /*Faz a conexao com o servidor*/
   if(connect(clienteSockfd,(struct sockaddr *)&serv_addr, addrlen) < 0)
     {
        	printf("Erro no Socket\n");
		exit(1);
	}
        return clienteSockfd;
}

void Cliente(int clienteSockfd)
{
  /*Buffer de dados a ser mandado para o servidor*/
  char buffer_para_servidor[256];
  printf("Digite uma mensagem para o servidor: ");
   do {

        scanf("%s",buffer_para_servidor);
        fflush(stdin);
        /*Escreve para o servidor*/

        write(clienteSockfd, buffer_para_servidor, sizeof (buffer_para_servidor));

      /*Mensagem para sair*/
    } while (strcmp(buffer_para_servidor, "sair") != 0);
    /**Encerra o descritor*/
    close(clienteSockfd);
}

int main()
{
    system("clear");
    /*Estrutura cliente*/
    struct sockaddr_in serv_addr;
    /*Tamanho da estrutura*/
    socklen_t addrlen = sizeof (serv_addr);
    /*Define o descritor cliente*/
    int descritorCliente;
    descritorCliente = configuracaoCliente();
    /*chama funcao do cliente passando o descritor*/
    Cliente(descritorCliente);
    exit(0);
}

Código Servidor. Para compilador utilize: gcc -lpthread -o servidor  servidor.c

/*********************************
Autor: Fernando Krein Pinheiro
Data: 04/07/2012
Linguagem: C
========= IMPORTANTE ===========
O código esta livre para usar,
citar e compartilhar desde que
mantida sua fonte e seu autor.
Obrigado.
*********************************
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <pthread.h>

void* Servidor(void* arg)
{
    /*Buffer de entrada (armazena buffer do cliente)*/
    char buffer_do_cliente[256];
    /*Cast do ponteiro*/
    int sockEntrada = *(int *) arg;
    /*Loop "infinito"*/
    printf("Aguardando as mensagens... ");
    for (;;)
    {
        /*Le o que vem do cliente*/
        read(sockEntrada, buffer_do_cliente, sizeof (buffer_do_cliente));
        if (strcmp(buffer_do_cliente, "sair") != 0)
        {
            /*Se buffer == sair cai fora*/
            printf("%s\n",buffer_do_cliente);
        }
        else
             {
                 /*Encerra o descritor*/
                 close(sockEntrada);
                 /*Encerra a thread*/
                 pthread_exit((void*) 0);
             }
    }
}

int configuracaoServidor()
{
    /*Cria o descritor*/
    int sockfd;
    /*Declaracao da estrutura*/
    struct sockaddr_in serverAddr;
    /*Cria o socket*/
    if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
	{
	  printf("Erro no Socket\n");
	  exit(1);
	}
    /*Zera a estrutura*/
    memset(&serverAddr, 0, sizeof (serverAddr));
    /*Seta a familia*/
    serverAddr.sin_family = AF_INET;
    /*Seta os IPS (A constante INADDR_ANY e todos os ips ou qualquer ip) htonl -> conversao*/
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    /*Define a porta*/
    serverAddr.sin_port = htons(6881);
    /*Faz a bindagem (cola, gruda, conecta seja o que for)*/
    if (bind(sockfd, (struct sockaddr *) & serverAddr, sizeof (serverAddr)) < 0)
    {
	  printf("Erro no Socket\n");
	  exit(1);
     }
    /*Fica na escuta de ate 5 clientes*/
    if (listen(sockfd, 5) < 0)
    {
	  printf("Erro no Socket\n");
	  exit(1);
    }
    return sockfd;
}

int main()
{
    system("clear");
    /*Declaracao da estrutura*/
    struct sockaddr_in serverAddr;
    /*Retorna da funcao e o descritor*/
    int sockfd = configuracaoServidor();

    /*Loop "infinito"*/
    while (1)
    {
    	int clienteSockfd;
    	struct sockaddr_in clienteAddr;
        /*tamanho da estrutura*/
    	unsigned int clntLen;
        clntLen = sizeof (clienteAddr);
        /*declara uma thread*/
	pthread_t thread;
	/*Fica no aguardo da conexao do cliente*/
        if ((clienteSockfd = accept(sockfd, (struct sockaddr *) & clienteAddr, &clntLen)) < 0)
        {
	  printf("Erro no Socket\n");
	  exit(1);
	}
        /*Inicializa a thread*/
        if (pthread_create(&thread, NULL, Servidor, &clienteSockfd) != 0)
       {
            printf("Erro na Thread\n");
            exit(1);
       }

        pthread_detach(thread);
    }
    exit(0);
}
Anúncios
por ferpinheiro Postado em C/C++

4 comentários em “Cliente – Servidor em C utilizando threads

  1. Show de bola cara. Estou fazendo uma cadeira de sistemas operacionais e vi esse assunto faz poucos dias. Consegui entender melhor o funcionamento do sistema com esses códigos.

    Alguma ideia de como utilizar esses programas para se comunicar entre dois computadores (um pc com o cliente e outro pc com o servidor)? Preciso saber o ip das máquinas?

    Abraços!

  2. meu caro obrigado pelo post, contdo estou tendo problemas para compilar o servidor. retorna-me a informacao abaixo

    /tmp/ccMJdIfZ.o: In function `main’:
    servidor.c:(.text+0x24d): undefined reference to `pthread_create’
    servidor.c:(.text+0x275): undefined reference to `pthread_detach’
    collect2: ld returned 1 exit status

    peco sua ajuda para solucionar

  3. Valeu pelos códigos acima. Vão ser muito úteis para uma atividade de redes que o professor solicitou para ser feita. Quem compartilha multiplica conhecimento.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s