Search code examples
cmultithreadingclienttcpclient

Launch a TCP client and server in the same program (in c)


I am studying in france ,sorry for my english , i have a project to realize, i program an industreille machine with a client tcp and i have to send the sensor information on tcp server, I wanted to know how with the threads I could run the client and the server on the same program at the same time,I am not a good programmer please help me ...

client :

/*************    BIBIOTHEQUE   *********************/
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <unistd.h>

/*************      SORTIES   ***********************/
#define EJECTION_PIECE                 0x01   // bit 0
#define ASPIRATION_ONA                 0x02   // bit 1
#define EXPULSION_VENTOUSE             0x04   // bit 2
#define BRAS_POSITION_MAGASINA         0x08   // bit 3
#define BRAS_POSITION_MODULE_CONTROLEA 0x10   // bit 4  0001 1000  0X18

/*************     ENTREES   ************************/
#define NON_DISPONIBLE                0x01  // bit 0   1   1
#define EJECTION_PIECE_RETRACTE       0x02  // bit 1   1   0
#define EJECTION_PIECE_AVANCE         0x04  // bit 2   0   1
#define ASPIRATION_ON                 0x08  // bit 3   0   0
#define BRAS_POSITION_MAGASIN         0x10  // bit 4   0   0
#define BRAS_POSITION_MODULE_CONTROLE 0x20  // bit 5   0   0
#define RESERVE_PIECE_VIDE            0x40  // bit 6   1   0
#define ASPIRATION_OFF                0x80  // bit 7   1   1

/*************     PORT & IP  ************************/
#define  PORT1  4200
#define  PORT2 4200
#define  IP2   "172.16.1.24"  //serveur Tcp

SOCKADDR_IN info_Trame;
SOCKADDR_IN envoie_donnee_serveur;

/*int nombre_de_caractere;
int nombre_de_caractere_recu ;
int nombre_de_caractere_recu_Capteur;
int nombre_caractere_recu_serveur;
int nombre_de_caractere_envoi_serveur;
int nombre_de_caractere_Capteur;

char buffer1[50];
//char buffer2[50];
char buffer3[50];
*/

SOCKET configurationTCP(char ip[], uint16_t port)
{
    SOCKET id_de_la_socket;

    WSADATA initialisation_win32; /// Variable pour récupérer la structure d'information sur l'initialisation
    int erreur;

    printf("programme client tcp\n");

    erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
    if (erreur!=0)
        printf("\n impossible d'initialiser Winsock  : %d %d",erreur,WSAGetLastError());
    else
        printf("\n WSAStartup  réussi ");

    // Ouverture d'une Socket
    //id_de_la_socket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);   /// Ouverture d'une Socket
    id_de_la_socket=socket(AF_INET,SOCK_STREAM,0);
    printf("id socket =%d\n",id_de_la_socket);
    if (id_de_la_socket==INVALID_SOCKET)
        printf("\n impossible de creer la socket  : %d ",WSAGetLastError());
    else
        printf("\n socket valider \n ");


    // OUVERTURE DE SESSION TCP
    info_Trame.sin_family=AF_INET;
    info_Trame.sin_addr.s_addr=inet_addr(ip);
    info_Trame.sin_port = htons(port);
    erreur=connect(id_de_la_socket,(struct sockaddr*)&info_Trame,sizeof(info_Trame));
    if (erreur!=0)
        printf("\n impossible d'ouvrir la session TCP : %d %d",erreur,WSAGetLastError());
    else
        printf("\n OUVERTURE DE SESSION TCP : OK \n ");

    return id_de_la_socket;
}



void fermetureTCP(SOCKET id_de_la_socket)
{
    int erreur;

    erreur=shutdown(id_de_la_socket,2); // 2 signifie socket d'émission et d'écoute
    if (erreur!=0)
        printf("\n Desole, je ne peux pas fermer la session TCP du a l'erreur : %d %d",erreur,WSAGetLastError());
    else
        printf("\n Session TCP : Arreter \n ");

    // FERMETURE DE LA SOCKET
    erreur=closesocket(id_de_la_socket);
    if (erreur!=0)
        printf("\n Desole, je ne peux pas arreter la socket machine du a l'erreur : %d %d",erreur,WSAGetLastError());
    else
        printf("\n Socket machin : Arreter \n");

    // Fermeture de WSAStartup
    erreur=WSACleanup();
    if (erreur!=0)
        printf("\n Desole, je ne peux pas liberer winsock du a l'erreur : %d %d",erreur,WSAGetLastError());
    else
        printf("\n WSACleanup : OK \n");
    getchar();
}


void ecritureModbus(SOCKET id_de_la_socket, unsigned char donnees1, unsigned char donnees2)
{
    unsigned char trameModbus[12]= {0x6c ,0x1f, 0x00, 0x00, 0x00, 0x06, 0xff, 0x06,0x9c,0x42};
    unsigned char buffer[50];
    int nombre_de_caractere_recu, i;
    int nombre_de_caractere;

    trameModbus[10] = donnees1;
    trameModbus[11] = donnees2;

    nombre_de_caractere=send(id_de_la_socket,(char *)trameModbus,12,0);

    if (nombre_de_caractere==SOCKET_ERROR)
        printf("\n Desole, je n'ai pas envoyer les donnees du a l'erreur : %d",WSAGetLastError());
    else
        printf("\n send trame     : OK");

    nombre_de_caractere_recu=recv(id_de_la_socket,(char *)buffer,12,0);
    if (nombre_de_caractere_recu==SOCKET_ERROR)
        printf("\n Desole, je n'ai pas recu de donnee de la trame ");
    else
    {
        printf("\nTrame modbus reçue : ");
        for(i=0; i< nombre_de_caractere_recu; i++)
        {
            printf("%x ",buffer[i]);
        }
        printf("\n");
    }
}

unsigned char lectureModbus(SOCKET id_de_la_socket, unsigned char donnees1, unsigned char donnees2 )  //tram modbus capteur
{
    unsigned char trameModBus_capteur[12]= {0x50, 0xa2, 0x00, 0x00, 0x00, 0x06, 0xff, 0x03, 0xb1, 0x53};
    unsigned char buffer[50];
    int nombre_de_caractere_recu_capteur, i;
    int nombre_de_caractere_capteur;
    trameModBus_capteur[10] = donnees1;
    trameModBus_capteur[11] = donnees2;

    nombre_de_caractere_capteur=send(id_de_la_socket,(char *)trameModBus_capteur,12,0);
    if (nombre_de_caractere_capteur==SOCKET_ERROR)
        printf("\nFonction modbus 3 : probleme envoi trame : %d",WSAGetLastError());
    else
        printf("\nsend trame     : OK\n");

    nombre_de_caractere_recu_capteur=recv(id_de_la_socket,(char *)buffer,12,0);
    if (nombre_de_caractere_recu_capteur==SOCKET_ERROR)
        printf("\nFonction modbus 3 : probleme reception trame");
    else
    {
        printf("\nTrame modbus reçue de la fonction 3 : ");
        for(i=0; i< nombre_de_caractere_recu_capteur; i++)
        {
            printf("%x ",buffer[i]);
        }
        printf("\n");
    }
    return buffer[10];
}

unsigned char mettreBrasEnRepos(SOCKET id_de_la_socket, unsigned char sorties)
{

    unsigned char entrees;
    entrees=lectureModbus(id_de_la_socket,0x00, 0x01);
    printf("\n entrees = %x\n",entrees);
    if( ( entrees & BRAS_POSITION_MAGASIN) ==  BRAS_POSITION_MAGASIN)
    {
        sorties=BRAS_POSITION_MODULE_CONTROLEA^sorties;
        ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties);
        Sleep(1855 );
        sorties=(~BRAS_POSITION_MODULE_CONTROLEA)&sorties;
        ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties);
    }
    if( ( entrees & BRAS_POSITION_MODULE_CONTROLE) ==  BRAS_POSITION_MODULE_CONTROLE)
    {
        sorties=BRAS_POSITION_MAGASINA^sorties;
        ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties);
        Sleep(1860 );
        sorties=(~BRAS_POSITION_MAGASINA)&sorties;
        ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties);
    }
    return sorties;
}




unsigned char  test_reservoir_plus_action(SOCKET id_de_la_socket, unsigned char sorties )
{
    unsigned char entrees;
    int vide;


    entrees=RESERVE_PIECE_VIDE;
    if(  (entrees & RESERVE_PIECE_VIDE) ==  RESERVE_PIECE_VIDE )
    {


    }

    // Boucle d'attente reserve vide
    vide=1;


    do
    {
        entrees=lectureModbus(id_de_la_socket,0x00, 0x01);
        printf("entrees = %x\n",entrees);
        if( ( entrees & RESERVE_PIECE_VIDE) ==  RESERVE_PIECE_VIDE)
        {
            printf("Reserve vide  !!!\n");
        }
        else
        {
            vide=0;
        }

    }
    while( vide == 1 );
    printf("sorties = %X\n",sorties);
    sorties=EJECTION_PIECE^sorties;
    ecritureModbus(id_de_la_socket,(unsigned char)0x00, sorties);  /// Probleme

    return sorties;
}


unsigned char  test_brasgauche_plus_action(SOCKET id_de_la_socket, unsigned char sorties )
{
    unsigned char entrees;



    entrees=lectureModbus(id_de_la_socket,0x00, 0x01);
    printf("\n entrees = %x\n",entrees);
    if( ( entrees & BRAS_POSITION_MODULE_CONTROLE) ==  BRAS_POSITION_MODULE_CONTROLE)
    {
        printf("Bras n'est pas a droit \n");
    }
    else
    {

        sorties=BRAS_POSITION_MAGASINA^sorties;
        ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties);
    }
    Sleep(3000);

    return sorties;
}


Serveur :


unsigned char  test_aspirationon_plus_action(SOCKET id_de_la_socket, unsigned char sorties )
{

    unsigned char entrees;

    entrees=lectureModbus(id_de_la_socket,0x00, 0x01);
    printf("\n entrees = %x\n",entrees);
    if( ( entrees & ASPIRATION_ON) ==  ASPIRATION_ON)
    {
        printf("Bras n'est pas a droit \n");
    }
    else
    {
        sorties=ASPIRATION_ONA^sorties;
        ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties);
    }

    return sorties;
}


unsigned char  test_brasdroite_plus_action(SOCKET id_de_la_socket, unsigned char sorties )
{

    unsigned char entrees;

    entrees=lectureModbus(id_de_la_socket,0x00, 0x01);
    printf("\n entrees = %x\n",entrees);
    if( ( entrees & BRAS_POSITION_MODULE_CONTROLE) ==  BRAS_POSITION_MODULE_CONTROLE)
    {
        printf("Bras n'est pas a droit \n");
    }
    else
    {

        sorties=BRAS_POSITION_MAGASINA^sorties;
        ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties);
    }
    Sleep(3000);


    return sorties;
}


unsigned char  test_aspiratiooff_plus_action(SOCKET id_de_la_socket, unsigned char sorties )
{

    unsigned char entrees;

    entrees=lectureModbus(id_de_la_socket,0x00, 0x01);
    printf("\n entrees = %x\n",entrees);
    if( ( entrees & ASPIRATION_OFF) ==  ASPIRATION_OFF)
    {
        printf("Bras n'est pas a droit \n");
    }
    else
    {
        sorties=EXPULSION_VENTOUSE^sorties;
        ecritureModbus(id_de_la_socket,(unsigned char)0x0, sorties);
    }

    return sorties;
}



int main()
{
    unsigned char sorties=0x00;
    unsigned char sorties1=0x01;
    unsigned char entrees;
    unsigned char car='a';
    int nombre_caractere_recu_serveur;
    int nombre_de_caractere_envoi_serveur;
    int vide,gauche,droite,retracter,etape;

    SOCKET id_de_la_socket=configurationTCP("192.168.10.244",502);
    SOCKET id_de_la_socket2=configurationTCP("172.16.1.24",4200);


    sorties=mettreBrasEnRepos(id_de_la_socket,sorties);
    Sleep(3000);

    sorties=test_reservoir_plus_action(id_de_la_socket,sorties);

    Sleep(3000);
    sorties=test_brasgauche_plus_action(id_de_la_socket,sorties);
    Sleep(3000);
    sorties=test_aspirationon_plus_action(id_de_la_socket,sorties);
    Sleep(3000);
    sorties=test_brasdroite_plus_action(id_de_la_socket,sorties);
    Sleep(3000);
    sorties=test_aspiratiooff_plus_action(id_de_la_socket,sorties);


    /*
      //lectureModbus(id_de_la_socket,0x00, 0x01);
       printf("sorties =%x\n",car);
       // nombre_de_caractere_envoi_serveur=send(id_de_la_socket2,(char *)&car,1,0);  // partie envois supoervisuer ou mon serveur tcp
         nombre_de_caractere_envoi_serveur=send(id_de_la_socket2,(char *)"sortie=X",9,0);  // partie envois supoervisuer ou mon serveur tcp
        if (nombre_de_caractere_envoi_serveur==SOCKET_ERROR)

            printf("\n Desole, je n'ai pas envoyer les donnees du a l'erreur : %d",WSAGetLastError());
        else
        {

            printf("\n send donnee  Serveur  : OK : %d",nombre_de_caractere_envoi_serveur);

        }
    */

    fermetureTCP(id_de_la_socket);
    fermetureTCP(id_de_la_socket2);
    return 0;
}

#include <stdio.h>
#include <clib.h>

#define PORT_ECHO                        7    /*well known echo port*/
#define TCPECHOBUF_SERVER_RECVSIZE    1024


static char recvbuf[TCPECHOBUF_SERVER_RECVSIZE];
static char ClientIP[INET_ADDRSTRLEN];



/******************************************************************************
* main()                                                                      *
******************************************************************************/
int main(void)
{
   struct sockaddr_in   addr;
   struct sockaddr_in   claddr;

   int sd;
   int asd;
   int established = 0;
   int i;
   int retval;
   int error;

   printf("\r\nTCPserver, listening on port %d\r\n",PORT_ECHO);

   sd = opensocket( SOCK_STREAM, &error );
   if(sd == API_ERROR)
   {
       printf("\r\nSocket open failed: %d",error);
       return -1;
   }

   addr.sin_family      =  PF_INET;
   addr.sin_port        =  htons(PORT_ECHO);
   addr.sin_addr.s_addr =  0L;

   retval = bind( sd, (const struct sockaddr *)&addr, &error );
   if(retval == API_ERROR)
   {
       printf("\r\nTCPserver: Socket bind failed: %d",error);
       return -1;
   }


    /**********************************************************************
    *Listen for connections                                               *
    **********************************************************************/
     printf("\r\nTCPserver: Listening for connection");
     retval = listen( sd, 1, &error );
     if(retval == API_ERROR)
     {
         printf("\r\nTCPserver: Socket listen failed: %d",error);
         return -1;
     }
   while(1)
   {
     /**********************************************************************
     *accept, establish a connection                                       *
     **********************************************************************/
     claddr.sin_family      =  PF_INET;
     claddr.sin_port        =  0;
     claddr.sin_addr.s_addr =  0L;

     retval = accept( sd, (struct sockaddr *)&claddr, &error );
     if(retval == API_ERROR)
     {
         printf("\r\nTCPserver: Socket accept failed: %d",error);
         return -1;
     }

     //save the new socket descriptor
     asd = retval;
     established = 1;

     InetToAscii( (unsigned long *) &claddr.sin_addr.s_addr, (char *) ClientIP );

     printf("\r\nTCPserver: Connected with %s , Port %u\r\n",ClientIP, htons(claddr.sin_port));
     while(established)
     {
printf("1");
       /********************************************************************
       *Wait for incoming data from the client                             *
       ********************************************************************/
       do
       {
printf("2");
          retval = recv( asd, (char *)recvbuf, TCPECHOBUF_SERVER_RECVSIZE,
          MSG_TIMEOUT, 20000L, &error );
          printf("retval=%d ",retval);
          printf("car=%c ",recvbuf[0]);
          recvbuf[0]=recvbuf[0]+1;
          if(retval == API_ERROR)
          {
             printf("\r\nTCPserver: Receive error %d",error);
             established = 0;
             break;
          }
          else
          {
             if( retval > 0)    //data received
             {
				 printf("\r\nTCPserver: Received data\r\n");
				 for(i=0;i<retval; i++)
				 {
				   printf("%02X ",(char)recvbuf[i]);
				 }
				 printf("\r\n");
				 /********************************
				  echo data back to the client
				 ********************************/
				 retval = send( asd, (char *)recvbuf, retval, 0, &error );
    printf("3");
				 if(retval == API_ERROR)
				 {
					printf("\r\nTCPserver: Send error %d",error);
					established = 0;
					break;
				 }
             }
          }
          /*****************************************************************
           Check, if there is more data available at the socket
          *****************************************************************/
          retval = GetWaitingBytes( asd, &error );
       }//while data available
       while((retval!=API_ERROR) && (retval>0));
     }//while(established)


     //close socket, given from accept
     printf("\r\nTCPserver: Closing connection");
     retval = closesocket( asd, &error );
     if(retval==API_ERROR)
     {
      printf("\r\nTCPserver: Socket close failed: %d",error);
     }
   }//while(1)

   /************************************
    Shutdown server, should not happen
    ************************************/

   printf("\r\nTCPserver: Closing listening socket");
   retval = closesocket( sd, &error );
   if(retval==API_ERROR)
   {
    printf("\r\nTCPserver: Socket close failed %d",error);
   }
   return 0;
}
// End of file


Solution

  • I'm not sure what you mean by "in the same program". You currently have two different programs (as you have two int main(void) functions). You could use multithreading to have both the client and the server in a single executable, but I fail to see a situation in which this could be advantageous.

    If you want more concrete help, I would suggest making a smaller example that exhibits more precisely how you are currently trying to use threads. Otherwise, it might be wise to look up a simple multithreading tutorial, and adding to it until it reaches the level of complexity you currently seem you have in your program.