multithreaded client em C
Autor: Eduardo A Bortolini | Publicado: 2012-06-02T15:18:00-03:00

Olá pessoal, hoje vamos implementar um cliente multithread em C. Na verdade ele não faz muita coisa, mas o objetivo é gerar um número de conexões que irão ou não se desconectar do servidor, ou seja, pode funcionar como um programa teste para o seu servidor.

Para facilitar o nosso entendimento, vamos dividir nosso projeto em arquivos. Nosso arquivos serão os seguintes:
Para funções de entrada de dados e nossos tipos:
Data.c
Data.h

Para nossas funções de rede:
Functions.c
Functions.h

Nosso programa principal:
main.c

Nosso makefile
Makefile

===========================Data.h========================================

#ifndef DATA_H
#define DATA_H

typedef enum op
{
 CONNECTTERMINATE = 1,
 CONNECTWAIT
} Eoptions;

typedef struct configurations{
 int numberOfConnections;
 char * ip;
 int port;
 Eoptions opConf;
 int socketId;
}config;

int splitOptions(char ** input, config * settings);
#endif

===========================Data.c========================================



#include&lt;string.h&gt;

#include&lt;stdlib.h&gt;

#include"Data.h"

#include&lt;stdio.h&gt;



int printSettings(config * settings){

 if(settings == NULL){

  return -1;

 }

 printf("\n\tNumber of Connections: %d", settings-&gt;numberOfConnections);

 printf("\n\tIP of server: %s", settings-&gt;ip);

 printf("\n\tPort of server: %d", settings-&gt;port);

 printf("\n\tConnections options: %d",settings-&gt;opConf);

 return 1;

}



int splitOptions(char ** input, config * settings){



 if(input == NULL)

  return 0;

 if(settings == NULL)

  return 0;

 settings-&gt;numberOfConnections = atoi(input[1]);

 settings-&gt;ip = input[2];

 settings-&gt;port = atoi(input[3]);

 settings-&gt;opConf = atoi(input[4]);

 //Enable to debug

 //printSettings(settings);



 return 1;

}




===========================Functions.h=====================================




#ifndef FUNCTIONS_H

#define FUNCTIONS_H

#include &lt;sys/types.h&gt;

#include &lt;sys/socket.h&gt;

#include &lt;netinet/in.h&gt;

#include "Data.h"







void setLocal(struct sockaddr_in * clientAddr);

void setRemote(struct sockaddr_in * serverAddr, char* serverIp, int port);

void &nbsp;mainClient(config* settings);





#endif





===========================Functions.c=====================================

#include &lt;stdio.h&gt;

#include &lt;sys/types.h&gt;

#include &lt;sys/socket.h&gt;

#include &lt;netinet/in.h&gt;

#include &lt;string.h&gt;

#include "Functions.h"

#include &lt;arpa/inet.h&gt;

#include &lt;unistd.h&gt;

#include &lt;string.h&gt;



int sendStr(config * settings, char * message){

 char buffer[255];

 if(settings == NULL)

  return -1;

 strcpy(buffer,message);

 send(settings-&gt;socketId,buffer,strlen(buffer),0);



 return 1;

}



void setLocal(struct sockaddr_in * clientAddr){

 memset((void *) clientAddr, 0, sizeof(struct sockaddr_in));

 if(clientAddr==NULL){

  printf("\n\tClient struct is null in setLocal");

 }

 clientAddr-&gt;sin_family = AF_INET;

 clientAddr-&gt;sin_addr.s_addr = INADDR_ANY;

 clientAddr-&gt;sin_port = 0;



}



void setRemote(struct sockaddr_in * serverAddr, char* serverIp, int port){

 serverAddr-&gt;sin_family = AF_INET;

 serverAddr-&gt;sin_addr.s_addr = inet_addr(serverIp);

 serverAddr-&gt;sin_port = htons(port);





}



void mainClient(config * settings){

 struct sockaddr_in  clientAddr, serverAddr;

 int sock;

 setLocal(&amp;clientAddr); //local settings

 setRemote(&amp;serverAddr,settings-&gt;ip,settings-&gt;port);

 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

 settings-&gt;socketId = sock;

 bind(sock, (const struct sockaddr *) &amp;serverAddr, sizeof(serverAddr));

 printf("\n\tConnecting");

 if (connect(sock, (const struct sockaddr *) &amp;serverAddr, sizeof(serverAddr)) != 0) {

  perror("client");

  return;

 }



 if(settings-&gt;opConf == CONNECTTERMINATE){

  sendStr(settings, "I will close in ten seconds");



  sleep(10);

  close(sock);

 }

 else{

  sendStr(settings, "I will never close");

  while(1){



   sleep(10);

  }

 }



}





===========================main.c=====================================

#include&lt;stdio.h&gt;

#include&lt;pthread.h&gt;

#include"Functions.h"

#include"Data.h"



int main(int argc, char** argv){

 config settings;

 int cont;

 pthread_t thread[10];

 if(argc != 5){

  printf("\n\tInvalid options.");

  printf("\n\tUsage: MultiThreadClient Ncon IP Port option");

  printf("\n\tNcon - Number of connections");

  printf("\n\tIP - Server IP");

  printf("\n\tPort - Port server is listening");

  printf("\n\tOption: \n\t1: connect and terminate\n\t2: connect and never terminate");

  return 0;

 }



 if(splitOptions(argv, &amp;settings) == 0)

  return 0;

 for(cont = 0; cont &lt; settings.numberOfConnections; cont++){

  printf("\n\tCreatingthread: %d", cont);

  pthread_create( &amp;thread[cont], NULL,(void*) &amp;mainClient , (void *)&amp;settings);

 }

 printf("\n\tPress a key");

 getchar();

 return 1;

}





===========================Makefile=====================================

CC=gcc

CFLAGS=-W -Wall -g

SRC= $(wildcard *.c)

OBJ= $(SRC:.c=.o)



all: clean $(OBJ)

 gcc -o MultiThreadClient $(OBJ) -lpthread

%.o: %.c

 @$(CC) -o $@ -c $&lt; $(CFLAGS)

clean:

 rm -f *.o&nbsp;




Para executar:


./MultiThreadClient 8 127.0.0.1 4001 1




ou


./MultiThreadClient 8 127.0.0.1 4001 2




Estamos assumindo que você possui um server em seu pc local escutando na porta 4001.&nbsp;