Thread: Socket buffer processing, start repeating data and get lost

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

    Socket buffer processing, start repeating data and get lost

    Hello guys

    I'm having difficulty in a routine that will receive data via Socket and Send to a CAN interface.

    My routine identifies a Bytes sequence, separates 13 bytes and processes, however some part of the code causes it to sometimes process the same buffer twice, I could not identify where ...

    Code:
    //Receive a message from client
        while( (readSize = recv(sock , mensagemRecebida , TAM_BUFFER_RX_SOCKET , 0)) > 0 )
        {
        	for(contador=0; contador<readSize; contador++)
        		args.arg1Dados[contador] = mensagemRecebida[contador];
    		args.arg2readSize = readSize;
    
        	if(pthread_create( &thread_Processar , NULL ,  &ProcessarDadosRecebidos , (void *)&args) < 0)
    		{
    			perror("could not create thread");
    			return 1;
    		}
    
        	//clear the message buffer
        	memset(mensagemRecebida, 0, TAM_BUFFER_RX_SOCKET);
        }
    Code:
    struct arg_struct {
        unsigned char arg1Dados[TAM_BUFFER_RX_SOCKET];
        int arg2readSize;
    };
    
    
    void *ProcessarDadosRecebidos(void *arguments)
    {
    	int idxNovoPacote=0;
    	int idxPosicaoInicioCAN = 0;
    	int idxPosicaoCharPacoteLido=0;
    
    	int ID_DESTINO_BT1 = 0;
    	int ID_DESTINO_BT2 = 0;
    	int DATASIZE = 0;
    	int ID_ORIGEM = 0;
    	int IDX_DEVICE = 0;
    	int IDX_FUNCAO_DEVICE = 0;
    
    	struct arg_struct *args = arguments;
    
    	unsigned char mensagemCANSeparada [DEFAULT_PACKET_CAN_SIZE];
    
    	for(idxPosicaoCharPacoteLido=0; idxPosicaoCharPacoteLido<args->arg2readSize; idxPosicaoCharPacoteLido++)
    	{
    		if (idxPosicaoCharPacoteLido + 7 < args->arg2readSize)
    		{
    			ID_DESTINO_BT1 = idxPosicaoCharPacoteLido;
    			ID_DESTINO_BT2 = idxPosicaoCharPacoteLido + 1;
    			DATASIZE = idxPosicaoCharPacoteLido + 4;
    			ID_ORIGEM = idxPosicaoCharPacoteLido + 5;
    			IDX_DEVICE = idxPosicaoCharPacoteLido + 6;
    			IDX_FUNCAO_DEVICE = idxPosicaoCharPacoteLido + 7;
    
    			if (args->arg1Dados[ID_DESTINO_BT1] == 0)
    			{
    				if (args->arg1Dados[ID_DESTINO_BT2] == 0)
    				{
    					if (args->arg1Dados[DATASIZE] == 8)
    					{
    						if (args->arg1Dados[ID_ORIGEM] == 0)
    						{
    							if (args->arg1Dados[IDX_DEVICE] > 0)
    							{
    								if (args->arg1Dados[IDX_FUNCAO_DEVICE] > 0)
    								{
    									idxPosicaoInicioCAN = idxPosicaoCharPacoteLido;
    
    									printf("Packet SEQ: %d Start Idx Of Packet %d Total Size: %d", contadorDebug, idxPosicaoInicioCAN, args->arg2readSize);
    
    									for(idxNovoPacote=0; idxNovoPacote<DEFAULT_PACKET_CAN_SIZE && idxNovoPacote<args->arg2readSize; idxNovoPacote++)
    									{
    										if(idxPosicaoInicioCAN < args->arg2readSize)
    										{
    											mensagemCANSeparada[idxNovoPacote] = args->arg1Dados[idxPosicaoInicioCAN];
    											idxPosicaoInicioCAN++;
    										}
    										else
    											printf("Tentativa de acessar indíce %d maior que a leitura de dados %d", idxPosicaoInicioCAN, args->arg2readSize);
    									}
    
    									printf(" Last Byte: %d\n", mensagemCANSeparada[idxNovoPacote - 1]);
    
    									idxPosicaoCharPacoteLido = idxPosicaoInicioCAN - 1;
    									contadorDebug++;
    									WriteCAN(mensagemCANSeparada, DEFAULT_PACKET_CAN_SIZE);
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    
    	idxPosicaoInicioCAN = 0;
    	// TODO - TRATAR SOBRAS DE PACOTES
    
    	return NULL;
    }
    Test Send Data (Last byte is Sequential)
    Seq[0] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 0
    Seq[1] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 1
    Seq[2] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 2
    Seq[3] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 3
    Seq[4] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 4
    Seq[5] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 5
    Seq[6] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 6
    Seq[7] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 7
    Seq[8] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 8
    Seq[9] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 9
    Seq[10] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 10
    Aguardando...10
    Seq[11] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 11
    Seq[12] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 12
    Seq[13] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 13
    Seq[14] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 14
    Seq[15] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 15
    Seq[16] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 16
    Seq[17] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 17
    Seq[18] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 18
    Seq[19] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 19
    Seq[20] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 20
    Seq[21] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 21
    Aguardando...21
    Seq[22] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 22
    Log Output (Last byte should be Sequencial)
    MapCANFrameToCharAndSend: Enviando dados CAN para SOCKET ID: 0 Size: 5
    Packet SEQ: 0 Start Idx Of Packet 0 Total Size: 13 Last Byte: 0
    Packet SEQ: 1 Start Idx Of Packet 13 Total Size: 130 Last Byte: 2
    Packet SEQ: 2 Start Idx Of Packet 26 Total Size: 130 Last Byte: 3
    Packet SEQ: 3 Start Idx Of Packet 39 Total Size: 130 Last Byte: 4
    Packet SEQ: 4 Start Idx Of Packet 52 Total Size: 130 Last Byte: 5
    Packet SEQ: 5 Start Idx Of Packet 65 Total Size: 130 Last Byte: 6
    Packet SEQ: 6 Start Idx Of Packet 78 Total Size: 130 Last Byte: 7
    Packet SEQ: 7 Start Idx Of Packet 91 Total Size: 130 Last Byte: 8
    Packet SEQ: 8 Start Idx Of Packet 104 Total Size: 130 Last Byte: 9
    Packet SEQ: 9 Start Idx Of Packet 117 Total Size: 130 Last Byte: 10

    START REPEAT DATA Received:
    Packet SEQ: 10 Start Idx Of Packet 0 Total Size: 130 Last Byte: 1
    Packet SEQ: 11 Start Idx Of Packet 13 Total Size: 130 Last Byte: 2
    Packet SEQ: 12 Start Idx Of Packet 26 Total Size: 130 Last Byte: 3

    Packet SEQ: 13 Start Idx Of Packet 39 Total Size: 130 Last Byte: 4
    Packet SEQ: 14 Start Idx Of Packet 52 Total Size: 130 Last Byte: 5
    Packet SEQ: 15 Start Idx Of Packet 65 Total Size: 130 Last Byte: 6
    Packet SEQ: 16 Start Idx Of Packet 78 Total Size: 130 Last Byte: 7
    Packet SEQ: 17 Start Idx Of Packet 91 Total Size: 130 Last Byte: 8
    Packet SEQ: 18 Start Idx Of Packet 104 Total Size: 130 Last Byte: 9
    Packet SEQ: 19 Start Idx Of Packet 117 Total Size: 130 Last Byte: 10
    Packet SEQ: 20 Start Idx Of Packet 0 Total Size: 13 Last Byte: 12
    Packet SEQ: 20 Start Idx Of Packet 0 Total Size: 13 Last Byte: 12
    Packet SEQ: 22 Start Idx Of Packet 0 Total Size: 13 Last Byte: 13
    Packet SEQ: 23 Start Idx Of Packet 13 Total Size: 104 Last Byte: 15
    Packet SEQ: 24 Start Idx Of Packet 26 Total Size: 104 Last Byte: 16
    Packet SEQ: 25 Start Idx Of Packet 39 Total Size: 104 Last Byte: 17

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Imagine the code creates 4 threads, and once the 4th thread is created they all execute each line at the same time. In that thought experiment, what does args point to? What are their values?

    gg

  3. #3
    Registered User
    Join Date
    Feb 2019
    Posts
    717
    Ahhhh, @sergioms, are you a fellow compatriot? (I'm brazillian!)... I've notice your code is writen in portuguese!

    Well... First: Notice recv() will return 0 for a stream blocking socket (TCP) only if the connection is shutdown (not if there is no more data to be read... And recv() can receive "pieces" of the data (that's why it returns a 'size'). Your loop should be something like this (it may contain errors... this is only an example):
    Code:
    ...
    char buffer[MAX_BUFFER];
    char *p;  // will point to buffer position where data will be writen.
    ssize_t ret_size, // returned size fromrecv().
            size;  // accumulated size of data received.
    
    size = 0;
    p = buffer; // points to the begining of the buffer.
    
    // Tries to read MAX_BUFFER bytes from socket.
    while ( size < MAX_BUFFER)
    {
      // fd is our stream socket file descriptor.
      if ( ( ret_size = (ssize_t)recv( fd, p, MAX_BUFFER - size, 0 ) ) <= 0 )
      {
        // handle error (ret_size = -1) or shutdown (ret_size = 0) here.
        ...
      }
    
      // Update size and advances p.
      size += ret_size;
      p += size;
    }
    ...
    Suppose that the receive queue is really small (1 KiB, for example) and you are trying to read 4100 bytes... Each round recv() could return 1024 and the last block would be 4 bytes long (4*1024+4 = 4100). So, 5 rounds!

    In the routine above, recv() may still block, waiting for another "piece" of data.

    Second: Since you are copying just the data received on your messagemRecebida buffer to args.arg1Dados buffer, why you need to fill the former with zeros? And since both have the same total size, there is no boundary issues. Why use that for loop to copy the buffer contents? This should be enough:
    Code:
    memcpy( args.arg1Dados, menssagemRecebida, args.arg2readSize = size );
    Third: There is no way to solve your problem without knowing the scope of your "receive" routine and its variables. If that secondary thread is started inside a function which lost scope as soon as you are zeroing messagemRecebida buffer and args is allocated on stack, then the thread could be dealing with a pointer to a region on the stack which is no longer valid (hence the garbage).

  4. #4
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    mensagemRecebida is my buffer read from socket in.

    I think this while is necessary, not to kill my thread .... it stays the whole time checking if something has arrived

    Code:
    while( (readSize = recv(sock , mensagemRecebida , TAM_BUFFER_RX_SOCKET , 0)) > 0 )

    I saw that to call threads with multiple arguments, the ideal is to create a structure.
    In this case, it contains the buffer and the read buffer size.

    Code:
        for(contador=0; contador<readSize; contador++)
                args.arg1Dados[contador] = mensagemRecebida[contador];
            args.arg2readSize = readSize;
     
            if(pthread_create( &thread_Processar , NULL ,  &ProcessarDadosRecebidos , (void *)&args) < 0)

  5. #5
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Hi flp1969,

    Yes, I am from Brazil, SC ... I work for Meitech (Industrial Automation Company) producing machines for chicken fridges.
    Very good to meet a fellow countryman here.



    Code:
    void *ConnectionHandler(void *socket_desc)
    {
        //Get the socket descriptor
        int sock = *(int*)socket_desc;
        int readSize;
        unsigned char mensagemRecebida[TAM_BUFFER_RX_SOCKET];
    
        pthread_t thread_Processar;
    
        puts ("Iniciou Thread ConnectionHandler");
    
        AddClientToConnectedList(sock);
        SendHelloCANToSocket();
    
        unsigned char *p;  // will point to buffer position where data will be writen.
        ssize_t size;  // accumulated size of data received.
    
        size = 0;
        p = mensagemRecebida; // points to the begining of the buffer.
    
    	// Tries to read MAX_BUFFER bytes from socket.
    	while ( size < TAM_BUFFER_RX_SOCKET)
    	{
    		// fd is our stream socket file descriptor.
    		if ( ( readSize = (ssize_t)recv( sock, p, TAM_BUFFER_RX_SOCKET - size, 0 ) ) <= 0 )
    		{
    			if(readSize == 0)
    			{
    				puts("Cliente Desconectado");
    				fflush(stdout);
    
    				RemoveClientFromConnectedList(sock);
    
    				return 1;
    			}
    			else if(readSize == -1)
    			{
    				perror("Falha ao Receber dados");
    				return 1;
    			}
    		}
    		else
    		{
    			ProcessarDadosRecebidos(p, readSize);
    
    			// Update size and advances p.
    			size += readSize;
    			p += size;
    		}
    	}
    
        return 0;
    }
    I changed the code as you suggested, I noticed that I did not really need Threads.

    However, apparently the code is an error when you have just read the data, I would like the routine to be in the listen mode, all the time waiting for the data to be received.

    Log received and error:
    Packet SEQ: 53 Start Idx Of Packet 104 Total Size: 130 Last Byte: 53
    Packet SEQ: 54 Start Idx Of Packet 117 Total Size: 130 Last Byte: 54
    Packet SEQ: 55 Start Idx Of Packet 0 Total Size: 13 Last Byte: 55
    Packet SEQ: 56 Start Idx Of Packet 0 Total Size: 130 Last Byte: 56
    Packet SEQ: 57 Start Idx Of Packet 13 Total Size: 130 Last Byte: 57
    Packet SEQ: 58 Start Idx Of Packet 26 Total Size: 130 Last Byte: 58
    Packet SEQ: 59 Start Idx Of Packet 39 Total Size: 130 Last Byte: 59
    Packet SEQ: 60 Start Idx Of Packet 52 Total Size: 130 Last Byte: 60
    Packet SEQ: 61 Start Idx Of Packet 65 Total Size: 130 Last Byte: 61
    Packet SEQ: 62 Start Idx Of Packet 78 Total Size: 130 Last Byte: 62
    Packet SEQ: 63 Start Idx Of Packet 91 Total Size: 130 Last Byte: 63
    Packet SEQ: 64 Start Idx Of Packet 104 Total Size: 130 Last Byte: 64
    Packet SEQ: 65 Start Idx Of Packet 117 Total Size: 130 Last Byte: 65
    Packet SEQ: 66 Start Idx Of Packet 0 Total Size: 13 Last Byte: 66
    Falha ao Receber dados: Bad address
    Segmentation fault (core dumped)
    Log Sent (Note that when I paused on the 66 sequence, there was the interrupt and error)
    Code:
    Seq[59] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 59 
    Seq[60] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 60 
    Seq[61] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 61 
    Seq[62] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 62 
    Seq[63] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 63 
    Seq[64] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 64 
    Seq[65] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 65 
    Aguardando...65
    Seq[66] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 66 
    Seq[67] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 67 
    Seq[68] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 68 
    Seq[69] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 69 
    Seq[70] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 70 
    Seq[71] Send Bytes : 0 0 0 1 8 0 1 2 1 2 3 4 71

  6. #6
    Registered User
    Join Date
    Feb 2019
    Posts
    717
    Quote Originally Posted by sergioms View Post
    Hi flp1969,

    Yes, I am from Brazil, SC ... I work for Meitech (Industrial Automation Company) producing machines for chicken fridges.
    Very good to meet a fellow countryman here.
    Vitória, ES!

    About your code... well... now you should use GDB to debug!

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,168
    > My routine identifies a Bytes sequence, separates 13 bytes and processes, however some part of the code causes it to sometimes process the same buffer twice, I could not identify where
    ...
    > if(pthread_create( &thread_Processar , NULL , &ProcessarDadosRecebidos , (void *)&args) < 0)
    Study this, and understand that passing a pointer to a local variable to a thread is just as bad as returning a pointer to a local variable from a function.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    void *good(void *p) {
        int *arg = p;
        printf("Value=%d\n",*arg);
        free(p);
        return NULL;
    }
    
    void *bad(void *p) {
        int *arg = p;
        printf("Value=%d\n",*arg);
        return NULL;
    }
    
    int main() {
        pthread_t   p[10];
        printf("Bad\n");
        for ( int i = 0 ; i < 10 ; i++ ) {
            pthread_create(&p[i],NULL,bad,&i);
        }
        for ( int i = 0 ; i < 10 ; i++ ) {
            pthread_join(p[i],NULL);
        }
    
        printf("Good\n");
        for ( int i = 0 ; i < 10 ; i++ ) {
            int *pi = malloc(sizeof(*pi));
            *pi = i;
            pthread_create(&p[i],NULL,good,pi);
        }
        for ( int i = 0 ; i < 10 ; i++ ) {
            pthread_join(p[i],NULL);
        }
    }
    Code:
    $ gcc foo.c -pthread
    $ ./a.out 
    Bad
    Value=2
    Value=3
    Value=3
    Value=7
    Value=7
    Value=5
    Value=8
    Value=8
    Value=10
    Value=10
    Good
    Value=0
    Value=1
    Value=2
    Value=3
    Value=4
    Value=5
    Value=6
    Value=7
    Value=8
    Value=9
    Bad will almost always print out some random sequence of duplicate and out of order nonsense, because all you gave it was a pointer to someone else's local variable.
    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.

  8. #8
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Thanks Salem,
    Now I changed the creation socket thread code like your suggestion, and not receiving/processing repeated data.

    But. System continue to receive only exacly the same quantity of bytes and stop:

    Packet SEQ: 361 Start Idx Of Packet 104 Total Size: 130 Last Byte: 107
    Packet SEQ: 362 Start Idx Of Packet 117 Total Size: 130 Last Byte: 108
    Packet SEQ: 363 Start Idx Of Packet 0 Total Size: 13 Last Byte: 109
    Packet SEQ: 364 Start Idx Of Packet 0 Total Size: 104 Last Byte: 110
    Packet SEQ: 365 Start Idx Of Packet 13 Total Size: 104 Last Byte: 111
    Packet SEQ: 366 Start Idx Of Packet 26 Total Size: 104 Last Byte: 112 Should continue processing from 26 to 104, jumping every 13 bytes ...
    Code:
    void *ConnectionHandler(void *socket_desc)
    {
        //Get the socket descriptor
        int sock = *(int*)socket_desc;
        int readSize;
        unsigned char mensagemRecebida[TAM_BUFFER_RX_SOCKET];
    
        //pthread_t thread_Processar;
    
        puts ("Iniciou Thread ConnectionHandler");
    
        AddClientToConnectedList(sock);
        SendHelloCANToSocket();
    
        //unsigned char *p;  // will point to buffer position where data will be writen.
        ssize_t size;  // accumulated size of data received.
    
        size = 0;
        //p = mensagemRecebida; // points to the begining of the buffer.
    
    	// Tries to read MAX_BUFFER bytes from socket.
    	while ( size < TAM_BUFFER_RX_SOCKET)
    	{
    		// fd is our stream socket file descriptor.
    		//if ( ( readSize = (ssize_t)recv( sock, p, TAM_BUFFER_RX_SOCKET - size, 0) ) <= 0 )
    		if ( ( readSize = (ssize_t)recv( sock, mensagemRecebida, TAM_BUFFER_RX_SOCKET, 0) ) <= 0 )
    		{
    			if(readSize == 0)
    			{
    				puts("Cliente Desconectado");
    				fflush(stdout);
    
    				RemoveClientFromConnectedList(sock);
    
    				return 1;
    			}
    			else if(readSize == -1)
    			{
    				perror("Falha ao Receber dados");
    				return 1;
    			}
    		}
    		else
    		{
    			ProcessarDadosRecebidos(mensagemRecebida, readSize);
    
    			// Update size and advances p.
    			//size += readSize;
    			//p += size;
    		}
    	}
    
    	printf("Chegou AQUI!");
    
        return 0;
    }
    
    void ProcessarDadosRecebidos(unsigned char mensagemRecebida[TAM_BUFFER_RX_SOCKET], int readSize)
    {
    	int idxNovoPacote=0;
    	int idxPosicaoInicioCAN = 0;
    	int idxPosicaoCharPacoteLido=0;
    
    	int ID_DESTINO_BT1 = 0;
    	int ID_DESTINO_BT2 = 0;
    	int DATASIZE = 0;
    	int ID_ORIGEM = 0;
    	int IDX_DEVICE = 0;
    	int IDX_FUNCAO_DEVICE = 0;
    
    	unsigned char mensagemCANSeparada [DEFAULT_PACKET_CAN_SIZE];
    
    	for(idxPosicaoCharPacoteLido=0; idxPosicaoCharPacoteLido<readSize; idxPosicaoCharPacoteLido++)
    	{
    		if (idxPosicaoCharPacoteLido + 7 < readSize)
    		{
    			ID_DESTINO_BT1 = idxPosicaoCharPacoteLido;
    			ID_DESTINO_BT2 = idxPosicaoCharPacoteLido + 1;
    			DATASIZE = idxPosicaoCharPacoteLido + 4;
    			ID_ORIGEM = idxPosicaoCharPacoteLido + 5;
    			IDX_DEVICE = idxPosicaoCharPacoteLido + 6;
    			IDX_FUNCAO_DEVICE = idxPosicaoCharPacoteLido + 7;
    
    			if (mensagemRecebida[ID_DESTINO_BT1] == 0)
    			{
    				if (mensagemRecebida[ID_DESTINO_BT2] == 0)
    				{
    					if (mensagemRecebida[DATASIZE] == 8)
    					{
    						if (mensagemRecebida[ID_ORIGEM] == 0)
    						{
    							if (mensagemRecebida[IDX_DEVICE] > 0)
    							{
    								if (mensagemRecebida[IDX_FUNCAO_DEVICE] > 0)
    								{
    									idxPosicaoInicioCAN = idxPosicaoCharPacoteLido;
    
    									printf("Packet SEQ: %d Start Idx Of Packet %d Total Size: %d", contadorDebug, idxPosicaoInicioCAN, readSize);
    
    									for(idxNovoPacote=0; idxNovoPacote<DEFAULT_PACKET_CAN_SIZE && idxNovoPacote<readSize; idxNovoPacote++)
    									{
    										if(idxPosicaoInicioCAN < readSize)
    										{
    											mensagemCANSeparada[idxNovoPacote] = mensagemRecebida[idxPosicaoInicioCAN];
    											idxPosicaoInicioCAN++;
    										}
    										else
    											printf("Tentativa de acessar indíce %d maior que a leitura de dados %d", idxPosicaoInicioCAN, readSize);
    									}
    
    									printf(" Last Byte: %d\n", mensagemCANSeparada[idxNovoPacote - 1]);
    
    									idxPosicaoCharPacoteLido = idxPosicaoInicioCAN - 1;
    									contadorDebug++;
    									WriteCAN(mensagemCANSeparada, DEFAULT_PACKET_CAN_SIZE);
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    
    	idxPosicaoInicioCAN = 0;
    	// TODO - TRATAR SOBRAS DE PACOTES
    }

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,168
    Imagine the message is ABCD.

    Now imagine you receive ABCDABCDAB

    Your ProcessarDadosRecebidos() will process two ABCD messages, and be left with AB.

    But you don't do anything with the trailing AB.

    So the next call to recv() is going to receive say "CDAB"

    You need to preserve the trailing message fragment, and then append the next recv() onto the end of it.

    Oh, and unless you're considering to write an else to every single one of these if statements,
    Code:
                if (mensagemRecebida[ID_DESTINO_BT1] == 0)
                {
                    if (mensagemRecebida[ID_DESTINO_BT2] == 0)
                    {
                        if (mensagemRecebida[DATASIZE] == 8)
                        {
                            if (mensagemRecebida[ID_ORIGEM] == 0)
                            {
                                if (mensagemRecebida[IDX_DEVICE] > 0)
                                {
                                    if (mensagemRecebida[IDX_FUNCAO_DEVICE] > 0)
    It would be better to write as
    Code:
                if (mensagemRecebida[ID_DESTINO_BT1] == 0 &&
                    mensagemRecebida[ID_DESTINO_BT2] == 0 &&
                    mensagemRecebida[DATASIZE] == 8 &&
                    mensagemRecebida[ID_ORIGEM] == 0 &&
                    mensagemRecebida[IDX_DEVICE] > 0 &&
                    mensagemRecebida[IDX_FUNCAO_DEVICE] > 0)
    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.

  10. #10
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Thank you Salem,

    It was already part of my plans to include the handling of packet leftovers, as I am handling the sending, I did a test routine to always send 13 bytes fixed.

    At the moment, my problem is that upon arriving at 366 packets of 13 bytes the system stops receiving data, but continues to execute. On the other side, the sending routine keeps sending new data ...

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,168
    I would suggest you just put recv() in a simple loop, just to make sure you can receive reliably.

    When you've got that sorted, then add the message parsing.
    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.

  12. #12
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    I just left the recv function within the while and ran normally, without errors, without crashing.

    However I have identified that the problem is in the ProcessarDadosRecebidos (ProcessDataReceived)

    Code:
    void *ConnectionHandler(void *socket_desc)
    {
        //Get the socket descriptor
        int sock = *(int*)socket_desc;
        int readSize;
        //unsigned char mensagemRecebida[TAM_BUFFER_RX_SOCKET];
    
        unsigned char *mensagemRecebida;
        mensagemRecebida = (unsigned char *) malloc(TAM_BUFFER_RX_SOCKET);
    
        puts ("Iniciou Thread ConnectionHandler!");
    
        AddClientToConnectedList(sock);
        SendHelloCANToSocket();
    
        ssize_t size;  // accumulated size of data received.
        size = 0;
    
    	// Tries to read MAX_BUFFER bytes from socket.
    	while ( size < TAM_BUFFER_RX_SOCKET)
    	{
    		readSize = (ssize_t)recv( sock, mensagemRecebida, TAM_BUFFER_RX_SOCKET, 0);
    
    		if (readSize <= 0)
    		{
    			if(readSize == 0)
    			{
    				puts("Cliente Desconectado");
    				fflush(stdout);
    
    				RemoveClientFromConnectedList(sock);
    
    				return 1;
    			}
    			else if(readSize == -1)
    			{
    				perror("Falha ao Receber dados");
    				return 1;
    			}
    		}
    		else
    		{
    			ProcessarDadosRecebidos(mensagemRecebida, readSize);
    		}
    	}
    
    	free(mensagemRecebida);
    	printf("Chegou AQUI!");
    
        return 0;
    }
    
    /*
     
     */
    
    void ProcessarDadosRecebidos(unsigned char mensagemRecebida[TAM_BUFFER_RX_SOCKET], int readSize)
    {
    	int idxNovoPacote=0;
    	int idxPosicaoInicioCAN = 0;
    	int idxPosicaoCharPacoteLido=0;
    
    	int ID_DESTINO_BT1 = 0;
    	int ID_DESTINO_BT2 = 0;
    	int DATASIZE = 0;
    	int ID_ORIGEM = 0;
    	int IDX_DEVICE = 0;
    	int IDX_FUNCAO_DEVICE = 0;
    
    	unsigned char *mensagemCANSeparada;
    	mensagemCANSeparada = (unsigned char *) malloc(DEFAULT_PACKET_CAN_SIZE);
    
    	for(idxPosicaoCharPacoteLido=0; idxPosicaoCharPacoteLido<readSize; idxPosicaoCharPacoteLido++)
    	{
    		if (idxPosicaoCharPacoteLido + 7 < readSize)
    		{
    			ID_DESTINO_BT1 = idxPosicaoCharPacoteLido;
    			ID_DESTINO_BT2 = idxPosicaoCharPacoteLido + 1;
    			DATASIZE = idxPosicaoCharPacoteLido + 4;
    			ID_ORIGEM = idxPosicaoCharPacoteLido + 5;
    			IDX_DEVICE = idxPosicaoCharPacoteLido + 6;
    			IDX_FUNCAO_DEVICE = idxPosicaoCharPacoteLido + 7;
    
    			if (mensagemRecebida[ID_DESTINO_BT1] == 0 && mensagemRecebida[ID_DESTINO_BT2] == 0 &&
    				mensagemRecebida[DATASIZE] == 8 &&
    				mensagemRecebida[ID_ORIGEM] == 0 &&
    				mensagemRecebida[IDX_DEVICE] > 0 && mensagemRecebida[IDX_FUNCAO_DEVICE] > 0)
    			{
    				idxPosicaoInicioCAN = idxPosicaoCharPacoteLido;
    
    				//printf("\nPacket SEQ: %d Start Idx Of Packet %d Total Size: %d", contadorDebug, idxPosicaoInicioCAN, readSize);
    
    				for(idxNovoPacote=0; idxNovoPacote<DEFAULT_PACKET_CAN_SIZE && idxNovoPacote<readSize; idxNovoPacote++)
    				{
    					if(idxPosicaoInicioCAN < readSize && idxNovoPacote < DEFAULT_PACKET_CAN_SIZE)
    					{
    						mensagemCANSeparada[idxNovoPacote] = mensagemRecebida[idxPosicaoInicioCAN];
    						idxPosicaoInicioCAN++;
    					}
    					else
    					{
    						printf("Tentativa de acessar indíce %d maior que a leitura de dados %d", idxPosicaoInicioCAN, readSize);
    					}
    
    				}
    
    				printf(" Last Byte: %d\n", mensagemCANSeparada[idxNovoPacote - 1]);
    
    				idxPosicaoCharPacoteLido = idxPosicaoInicioCAN - 1;
    				//contadorDebug++;
    
    				WriteCAN(mensagemCANSeparada, DEFAULT_PACKET_CAN_SIZE);
    			}
    		}
    	}
    
    	idxPosicaoInicioCAN = 0;
    	free(mensagemCANSeparada);
    
    	// TODO - TRATAR SOBRAS DE PACOTES
    }

  13. #13
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Thanks All for support,

    There were no more errors in the code after your help.
    The error was now in the CAN interface of the machine that was having trouble clearing the message queue.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 17
    Last Post: 04-17-2012, 05:46 PM
  2. Packet processing in Socket programming, please help
    By pumpkin in forum Networking/Device Communication
    Replies: 5
    Last Post: 05-28-2009, 01:33 AM
  3. Replies: 7
    Last Post: 04-27-2009, 05:56 PM
  4. Data is lost somewhere ...
    By csonx_p in forum C++ Programming
    Replies: 10
    Last Post: 01-02-2009, 12:08 PM
  5. in socket, how to know send buffer is full?
    By 0000000009 in forum Networking/Device Communication
    Replies: 2
    Last Post: 10-26-2006, 05:27 AM

Tags for this Thread