Thread: Socket Message only receive / Not Send (Pthread Issue)

  1. #1
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184

    Socket Message only receive / Not Send (Pthread Issue)

    How to manage a thread to receive/accept incoming connections and data receive, and other thread calls to SocketSendData and really send messages.

    Actually some times messages are sended other times no....


    Code:
    /*
     * SocketServer.c
     *
     *  Created on: 5 de jul de 2018
     *      Author: sergiom
     */
    
    #include <stdio.h>
    #include <string.h>    			//strlen
    #include <stdlib.h>    			//strlen
    #include <sys/socket.h>
    #include <arpa/inet.h> 			//inet_addr
    #include <unistd.h>    			//write
    #include <pthread.h> 			//for threading , link with lpthread
    #include <netinet/in.h>
    
    #include "CANSocket.h"
    #include "SocketServer.h"
    
    int qtdClientesConectados=0;
    int arrClientesConectados[MAX_CLIENT_CONNECTED];
    
    int StartSocketServer()
    {
        int socket_desc , client_sock , c;
        struct sockaddr_in server , client;
        struct in_addr ip_dest;
        pthread_t thread_id;
        pthread_t threadSend;
    
        //Create socket
        socket_desc = socket(AF_INET , SOCK_STREAM , 0);
        if (socket_desc == -1)
        {
            printf("Não foi possÃ..vel Criar o Socket!");
        }
        puts("Socket: Criado!");
    
        ip_dest.s_addr = INADDR_ANY;
    
        //Prepare the sockaddr_in structure
        server.sin_family = AF_INET;
        server.sin_addr = ip_dest;
        server.sin_port = htons( DEFAULT_PORT_LISTENER );
    
        //Bind
        if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
        {
            //print the error message
            perror("bind failed. Error");
            return 1;
        }
    
        //Listen
        listen(socket_desc , 3);
        IniciarArrayConexao();
    
        //Accept and incoming connection
        puts("Socket: Aguardando conexões de entrada...");
        c = sizeof(struct sockaddr_in);
    
        while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
        {
            puts("Nova conexão aceita!");
    
            if(pthread_create( &thread_id , NULL ,  ConnectionHandler , (void*) &client_sock) < 0)
            {
                perror("could not create thread");
                return 1;
            }
            else
            {
            	puts("SocketSendData");
            	SocketSendData("TESTEENVIO", 9);
            }
    
            //Now join the thread , so that we dont terminate before the thread
            //pthread_join( thread_id , NULL);
        }
    
        if (client_sock < 0)
        {
            perror("accept failed");
            return 1;
        }
    
        return 0;
    }
    
    /*
     * This will handle connection for each client
     * */
    void *ConnectionHandler(void *socket_desc)
    {
        //Get the socket descriptor
        int sock = *(int*)socket_desc;
        int readSize;
        unsigned char *message , mensagemRecebida[TAM_BUFFER_RX_SOCKET];
    
        puts ("Iniciou Thread ConnectionHandler");
        AddClientToConnectedList(sock);
    
        //SendHelloCANToSocket();
    
        //Receive a message from client
        while( (readSize = recv(sock , mensagemRecebida , TAM_BUFFER_RX_SOCKET , 0)) > 0 )
        {
            //end of string marker
        	WriteCAN(mensagemRecebida, readSize);	// readSize);
    
    		//clear the message buffer
    		memset(mensagemRecebida, 0, TAM_BUFFER_RX_SOCKET);
        }
    
        if(readSize == 0)
        {
            puts("Cliente Desconectado");
            fflush(stdout);
    
            RemoveClientFromConnectedList(sock);
        }
        else if(readSize == -1)
        {
            perror("Falha ao Receber dados");
        }
    
        return 0;
    }
    
    void SocketSendData(unsigned char dataReadCAN[TAM_BUFFER_TX_SOCKET], int tamanho)
    {
    	for(int cont=0; cont<MAX_CLIENT_CONNECTED; cont++)
    	{
    		if(arrClientesConectados[cont] != -1)
    			write(arrClientesConectados[cont] , dataReadCAN , tamanho);
    	}
    
    	return;
    }
    
    void IniciarArrayConexao()
    {
    	for(int c=0; c<MAX_CLIENT_CONNECTED; c++)
    		arrClientesConectados[c] = -1;
    }
    
    void AddClientToConnectedList(int novaConexao)
    {
    	if(qtdClientesConectados < MAX_CLIENT_CONNECTED)
    	{
    		for(int cont=0; cont<MAX_CLIENT_CONNECTED; cont++)
    		{
    			if(arrClientesConectados[cont] == -1)
    			{
    				AddToConnectedList(cont, novaConexao, NORMAL_ADD_OPERATION);
    				return;
    			}
    		}
    		puts("SocketServer: Não encontrou espaço para adicionar nova conexão!\n");
    	}
    	else
    	{
    		AddToConnectedList(MAX_CLIENT_CONNECTED - 1, novaConexao, FORCE_OVERWRITE);
    
    		printf("SocketServer: Quantidade de clientes conectados ultrapassa o número máximo permitido: %d - Última posição foi sobrescrita!\n", MAX_CLIENT_CONNECTED);
    	}
    }
    
    void AddToConnectedList(int posicao, int novaConexao, bool forceOverwrite)
    {
    	arrClientesConectados[posicao] = novaConexao;
    
    	if(!forceOverwrite)
    		qtdClientesConectados++;
    
    	printf("SocketServer: Cliente adicionado a posição %d\n", posicao);
    }
    
    void RemoveClientFromConnectedList(int clienteDesconectado)
    {
    	for(int cont=0; cont<MAX_CLIENT_CONNECTED; cont++)
    	{
    		if(arrClientesConectados[cont] == clienteDesconectado)
    		{
    			arrClientesConectados[cont] = -1;
    			printf("SocketServer: Cliente removido da posição %d\n", cont);
    			qtdClientesConectados--;
    		}
    	}
    }

  2. #2
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Sorry, the problem was in my client socket routines.

    Code:
    /*
     * SckClienteTest.c
     *
     *  Created on: 13 de jul de 2018
     *      Author: sergiom
     */
    /*
        C ECHO client example using sockets
    */
    #include <stdio.h> //printf
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>    //strlen
    #include <sys/socket.h>    //socket
    #include <arpa/inet.h> //inet_addr
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <sys/time.h>
    
    #include "SckClienteTest.h"
    
    int sock;
    
    int main(int argc , char *argv[])
    {
    
        struct sockaddr_in server;
        //char message[1000];
    
        //Create socket
        sock = socket(AF_INET , SOCK_STREAM , 0);
        if (sock == -1)
        {
            printf("Could not create socket");
        }
        puts("Socket created");
    
        server.sin_addr.s_addr = inet_addr(IP_SERVER);
        server.sin_family = AF_INET;
        server.sin_port = htons( PORT );
    
        //Connect to remote server
        if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
        {
            perror("connect failed. Error");
            return 1;
        }
    
        puts("Connected\n");
    
        CreateThreads();
    
        close(sock);
        return 0;
    }
    
    int CreateThreads()
    {
    	if(pthread_create( &thread_id_rcv , NULL ,  TimerReadSocket) < 0)
    	{
    		perror("could not create thread");
    		return 1;
    	}
    	else
    	{
    		puts("SocketCAN: Thread TimerReadSocket started!");
    
    		if(pthread_create( &thread_id_write , NULL ,  TimerAskWriteSocket) < 0)
    		{
    			perror("could not create thread");
    			return 1;
    		}
    		else
    			puts("SocketCAN: Thread TimerAskWriteSocket started!");
    	}
    
    	pthread_join( thread_id_write , NULL);
    
    	return 0;
    }
    
    void *TimerReadSocket()
    {
    	int tamanho;
    	int cont=0;
    	unsigned char server_reply[2000];
    
    	while(1)
    	{
    		tamanho = recv(sock , server_reply , 2000 , 0);
    
            if(tamanho < 0)
            {
                puts("recv failed");
                break;
            }
            else
            {
            	printf("\nRecebido[%d]: ", tamanho);
    
            	for(cont=0; cont<tamanho; cont++)
            		printf("%d ", server_reply[cont]);
            }
    	}
    }
    
    void *TimerAskWriteSocket()
    {
    	int opcao;
    
    
    	while(1)
    	{
    		printf("\n[1] Mensagem [2] Bytes [3] Sair: ");
    		scanf("%d", &opcao);
    
    		if(opcao == 1)
    		{
    			 WriteText();
    		}
    		else if(opcao == 2)
    		{
    			WriteBytes();
    		}
    		else
    		{
    			break;
    			exit(0);
    		}
    
    		sched_yield();
    	}
    }
    
    void WriteText()
    {
    	char message[1000];
    
    	printf("\n\nDigite a mensagem: \n");
    	scanf("%s" , message);
    
    	//Send some data
    	if( send(sock , message , strlen(message) , 0) < 0)
    	{
    		puts("Send failed");
    		exit(0);
    	}
    }
    
    void WriteBytes()
    {
    	int retorno=0;
    	int cont=0;
    	int IDDestino;
    	int qtdBytes=-1;
    
    	char pacoteCompleto[MAX_BYTES_WRITE_CAN];
    
    	printf("\nDigite o ID: ");
    	scanf("%d" , &IDDestino);
    
    	pacoteCompleto[0] = (IDDestino >> 24) & 0xFF;
    	pacoteCompleto[1] = (IDDestino >> 16) & 0xFF;
    	pacoteCompleto[2] = (IDDestino >> 8) & 0xFF;
    	pacoteCompleto[3] = (IDDestino & 0xFF);
    
    	printf("\nDigite a quantidade de Bytes: ");
    	scanf("%d" , &qtdBytes);
    	pacoteCompleto[4] = qtdBytes;
    
    	for(cont=0; cont<qtdBytes; cont++)
    	{
    		scanf("%d" , &retorno);
    		pacoteCompleto[cont + 5] = retorno;
    	}
    
    	printf("\nAgora vai enviar para o Destino %d quantidade de %d bytes", IDDestino, qtdBytes);
    
    	//Send some data
    	if(send(sock , pacoteCompleto , cont + 5, 0) < 0)
    	{
    		puts("Send failed");
    	}
    	else
    		printf("\nPacote enviado: %d %d %d %d\n", pacoteCompleto[4], pacoteCompleto[5], pacoteCompleto[6], pacoteCompleto[7]);
    }

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Code:
        while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
        {
            puts("Nova conexão aceita!");
     
            if(pthread_create( &thread_id , NULL ,  ConnectionHandler , (void*) &client_sock) < 0)
    This is still wrong though.
    If you get two accepts in quick succession, the value in client_sock can be overwritten before the first thread has a chance to read it.

    You should create some unique storage (malloc is good for this).
    Code:
    int *sockForThread = malloc(sizeof(*sockForThread));
    *sockForThread = client_sock;
    if(pthread_create( &thread_id , NULL ,  ConnectionHandler , (void*) &client_sock) != 0) {  // check the manual page, < 0 is wrong
        // no thread, cleanup
        free(sockForThread);
    }
    The thread function does this
    Code:
    int *sockForThread = param;
    int socket = *sockForThread;
    free(sockForThread);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Thanks Salem.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Use one socket to send and receive message (using UDP)
    By tanya9x in forum C++ Programming
    Replies: 11
    Last Post: 02-28-2010, 05:58 AM
  2. Send/Receive
    By C_ntua in forum Networking/Device Communication
    Replies: 1
    Last Post: 01-19-2010, 12:17 PM
  3. send/receive udp from specific NIC
    By dsollen in forum Networking/Device Communication
    Replies: 2
    Last Post: 10-27-2009, 04:55 PM
  4. Receive a TCP message on a UDP socket?
    By Yarin in forum C++ Programming
    Replies: 5
    Last Post: 09-05-2009, 12:21 AM
  5. send and receive byte does not match
    By saipkjai in forum Networking/Device Communication
    Replies: 1
    Last Post: 02-09-2008, 01:09 AM

Tags for this Thread