Menu

Remplir les données reçues (server socket tcp)

Messages postés
38
Date d'inscription
mardi 23 avril 2019
Statut
Membre
Dernière intervention
17 mai 2019
- - Dernière réponse : [Dal]
Messages postés
5099
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mai 2019
- 2 mai 2019 à 16:22
Bonjour,


J'ai un capteur qui va m'envoyer au début l'état de DOORs(3portes) et après si l'une de porte est ouverte il va m'envoyer une liste de donnée : DoordID, DoorState et l'heure d'ouverture de porte.

J'ai essayé de créer deux sockets serveur tcp : le premier le serveur va écouter le port 8008 pour récupérer le DoorState et le deuxième va être à l'écoute du port 8080 pour récuperer les données de comptages (nombre montée , nombre de descends et le ID de porte)


socket 1:
 Door iris_http_tcp_doorstate(void)
{// Initialize Winsock.
    char recvbuf[1024]= {0};
	//int i;
    int recvbuflen = DEFAULT_BUFLEN;
    struct sockaddr_in service;
	SYSTEMTIME st;
    WSADATA wsaData;
    SOCKET ListenSocket;
    SOCKET AcceptSocket;
	Door  cp;
	char *reply = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 12\n\nAll received";
	 //char buffer[80];
	 int count = 1;
	 char TagValue[100]= {0};
	 char TagValue1[100]= {0};
	 char TagValue2[100]= {0};
	 char TagValue3[100]= {0};
	 char Tag1[] = "Value";

  int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

  if (iResult != NO_ERROR)

    LOG_INFO("Server: Error at WSAStartup().\n");

  else

    LOG_INFO("Server: WSAStartup() is OK.\n");






  // The sockaddr_in structure specifies the address family,

  // IP address, and port for the socket that is being bound.


  service.sin_family = AF_INET;

  service.sin_addr.s_addr = inet_addr("192.168.0.95");

  service.sin_port = htons(8008);


  
  // Create a SOCKET for listening for

  // incoming connection requests.

  ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (ListenSocket == INVALID_SOCKET)

  {

    LOG_INFO("Server: Error at socket(): %ld\n", WSAGetLastError());

    WSACleanup();

    //return 0;

  }

  else

    LOG_INFO("Server: socket() is OK.\n");


  if (bind(ListenSocket, (SOCKADDR*) &service,	sizeof(service)) == SOCKET_ERROR)

  {

    LOG_INFO("Server: bind() failed.\n");

    WSACleanup();

    //return -1;

  }

  else

    LOG_INFO("Server: bind() is OK.\n");



   // Listen for incoming connection requests on the created socket
  if (listen(ListenSocket, 10) == SOCKET_ERROR)
  {
    LOG_INFO("Server: Error listening on socket.\n");
	WSACleanup();
	//return -1;
  }

  else

    LOG_INFO("Server: listen() is OK.\n");



  // Create a SOCKET for accepting incoming requests.

  // Accept the connection if any...


while( count <4)
{
      AcceptSocket = accept(ListenSocket, (struct sockaddr*)&IRMAClient, &iIRMAClientLen);

            if (AcceptSocket == INVALID_SOCKET)

           {

                LOG_INFO("Server: accept() error %d\n", WSAGetLastError());

                WSACleanup();

                //return -1;

            }

           else

              LOG_INFO("Server: accept() is OK.\n");

              LOG_INFO("Server: accepted connection from %s, port %d\n", inet_ntoa(IRMAClient.sin_addr), htons(IRMAClient.sin_port)) ;

        iResult = recv(AcceptSocket, recvbuf, 1024, 0);
		//time (&rawtime);
		 //timeinfo = localtime (&rawtime);

		//strftime (buffer,80,"%Y%m%d-%X",timeinfo);

       

			if (iResult == SOCKET_ERROR)

				  {

				LOG_INFO("Server: recv() failed: error %d\n", WSAGetLastError());

				closesocket(AcceptSocket);


			}

		   else

				LOG_INFO("Server: recv() is OK.\n");

			if (iResult == 0)

			{

				printf("Server: Client closed connection.\n");

				closesocket(AcceptSocket);

			}
			
			LOG_INFO("Server: \n recvbuf = %s ", recvbuf);
			GetLocalTime(&st);
			sprintf(cp.Heure, "%04d%02d%02d-%02d:%02d:%02d" ,st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
			GetXmlTagValue(recvbuf,"DoorID",Tag1,TagValue);
			GetXmlTagValue(recvbuf,"OpenState",Tag1,TagValue1);
			cp.ID = atoi(TagValue);
			//LOG_INFO("Server: \n  Time = cp.ID \n\n recvbuf = %s ", recvbuf);
			sprintf(cp.Heure, TagValue1);
			//LOG_INFO("Server: \n  Time = %s \n\n recvbuf = %s ", recvbuf);
			//memcpy(Count_Pass, Count_Pass, 1);

			//LOG_INFO("Memmcpy: \n  Time = %s \n ID= %d \nNombre_Mont =%d \n Nombre_Desc = %d ", Count_Pass[i].Heure, Count_Pass[i].ID, Count_Pass[i].Nombre_Mont, Count_Pass[i].Nombre_Desc);
		send(AcceptSocket, reply, strlen(reply), 0);
		LOG_INFO("%s\n",reply);
		count++;
}		
  return cp;

}

Socket 2 :
Comptage * iris_http_tcp_Counting_Passengers(void)
{// Initialize Winsock.
    char recvbuf[1024]= {0};
	//int i;
    int recvbuflen = DEFAULT_BUFLEN;
    struct sockaddr_in service;
    WSADATA wsaData;
    SOCKET ListenSocket;
    SOCKET AcceptSocket;
	char *reply = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 12\n\nAll received";
	 SYSTEMTIME st;
	 Comptage * cp;

	 //char buffer[80];
	 int count = 0;
	 char TagValue[100]= {0};
	 char TagValue1[100]= {0};
	 char TagValue2[100]= {0};
	 char TagValue3[100]= {0};
	 char Tag1[] = "Value";
	 

  int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

  if (iResult != NO_ERROR)

    LOG_INFO("Server Comptage: Error at WSAStartup().\n");

  else

    LOG_INFO("Server Comptage : WSAStartup() is OK.\n");






  // The sockaddr_in structure specifies the address family,

  // IP address, and port for the socket that is being bound.


  service.sin_family = AF_INET;

  service.sin_addr.s_addr = inet_addr("192.168.0.95");

  service.sin_port = htons(8080);


  
  // Create a SOCKET for listening for

  // incoming connection requests.

  ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (ListenSocket == INVALID_SOCKET)

  {

    LOG_INFO("Server Comptage : Error at socket(): %ld\n", WSAGetLastError());

    WSACleanup();

  }

  else

    LOG_INFO("Server Comptage : socket() is OK.\n");


  if (bind(ListenSocket, (SOCKADDR*) &service,	sizeof(service)) == SOCKET_ERROR)

  {

    LOG_INFO("Server Comptage : bind() failed.\n");

    WSACleanup();

  }

  else

    LOG_INFO("Server Comptage: bind() is OK.\n");



   // Listen for incoming connection requests on the created socket
  if (listen(ListenSocket, 10) == SOCKET_ERROR)
  {
    LOG_INFO("Server Comptage : Error listening on socket.\n");
	WSACleanup();
  }

  else

    LOG_INFO("Server Comptage: listen() is OK.\n");



  // Create a SOCKET for accepting incoming requests.

  // Accept the connection if any...


cp = malloc(sizeof(Comptage) * 1024);

      AcceptSocket = accept(ListenSocket, (struct sockaddr*)&IRMAClient, &iIRMAClientLen);

            if (AcceptSocket == INVALID_SOCKET)

           {

                LOG_INFO("Server: accept() error %d\n", WSAGetLastError());

                WSACleanup();

            }

           else

              LOG_INFO("Server Comptage: accept() is OK.\n");

              //LOG_INFO("Server: accepted connection from %s, port %d\n", inet_ntoa(IRMAClient.sin_addr), htons(IRMAClient.sin_port)) ;

while(iris_http_tcp_doorstate().DoorState =="SingleDoorClose")
{
	LOG_INFO("Server: \n id = %d \n", iris_http_tcp_doorstate().ID);
}		
while((iris_http_tcp_doorstate().ID ==1 && iris_http_tcp_doorstate().DoorState =="SingleDoorOpen") || (iris_http_tcp_doorstate().ID ==2 && iris_http_tcp_doorstate().DoorState =="SingleDoorOpen") || (iris_http_tcp_doorstate().ID ==3 && iris_http_tcp_doorstate().DoorState =="SingleDoorOpen"))
{
        iResult = recv(AcceptSocket, recvbuf, 1024, 0);
		LOG_INFO("Server: \n  Time = %s \n ID= %d \n DoorState = %s", iris_http_tcp_doorstate().Heure, iris_http_tcp_doorstate().ID, iris_http_tcp_doorstate().DoorState);
		//time (&rawtime);
		 //timeinfo = localtime (&rawtime);

		//strftime (buffer,80,"%Y%m%d-%X",timeinfo);

        if (iResult == SOCKET_ERROR)

              {

            LOG_INFO("Server: recv() failed: error %d\n", WSAGetLastError());

            closesocket(AcceptSocket);

            continue;

        }

       else

            LOG_INFO("Server: recv() is OK.\n");

		if (cp == NULL)
			return NULL;

		GetLocalTime(&st);
		sprintf(cp[count].Heure, "%04d%02d%02d-%02d:%02d:%02d" ,st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
		GetXmlTagValue(recvbuf,"DoorID",Tag1,TagValue);
		GetXmlTagValue(recvbuf,"In",Tag1,TagValue1);
		GetXmlTagValue(recvbuf,"Out",Tag1,TagValue2);
		cp[count].ID = atoi(TagValue);
		cp[count].Nombre_Mont = atoi(TagValue1);
		cp[count].Nombre_Desc = atoi(TagValue2);
        LOG_INFO("Server: \n  Time = %s \n ID= %d \nNombre_Mont =%d \n Nombre_Desc = %d ", cp[count].Heure, cp[count].ID, cp[count].Nombre_Mont, cp[count].Nombre_Desc);


		//LOG_INFO("Memmcpy: \n  Time = %s \n ID= %d \nNombre_Mont =%d \n Nombre_Desc = %d ", Count_Pass[i].Heure, Count_Pass[i].ID, Count_Pass[i].Nombre_Mont, Count_Pass[i].Nombre_Desc);
	send(AcceptSocket, reply, strlen(reply), 0);
	LOG_INFO("%s\n",reply);
	LOG_INFO("Server: I'm waiting more connection, try running the client\n");
	LOG_INFO("Server: program from the same sensor or other sensor...\n");
	count++;
}

  return cp;

}


Mon soucis est le boucle while dans les deux sockets je ne sais pas quoi faire pour dire au serveur si l'une de portes (ou les trois ouvertes ) est ouverte tu lance le deuxième socket et remplir un tableau qui contient tout les données
Tableau 1: DoorId DoorState Date
Tableau 1: DoorId Nombre_montée Nombre_Descend Date

Avez-vous une idée SVP comment peux-je le faire? Avez-vous des remarque sur mon code svp?
Merci
Configuration: Windows / Chrome 73.0.3683.103
Afficher la suite 

Votre réponse

1 réponse

Messages postés
5099
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mai 2019
937
0
Merci
Salut emmy_2019,

Tu pourrais avoir une seule boucle où tu gères ce que attends sur chaque port en fonction de l'état des portes.

Tu as 3 portes, et les données provenant du port indiquant le statut des portes t'informent que l'une d'elle est ouverte, tu dois attendre des données sur l'autre port susceptible de recevoir les données concernant la montée et descente de passagers par une ou plusieurs portes.

Par exemple, tu peux représenter les états importants pour ton application sous la forme suivante :

#define DOORS_MAX   3

/* enum types for the various states */
enum all_doors_state        { ALL_CLOSED, SOME_OPENED };
enum a_door_state           { CLOSED, OPENED };

/* variables for storing states */
enum all_doors_state        all_doors_state;
enum a_door_state           a_door_state[DOORS_MAX];

int main(void) {
    /* init states */
    all_doors_state = ALL_CLOSED;
    for (int n = 0; n < DOORS_MAX; n++)
        a_door_state[n] = CLOSED;

    /* init the two servers */
    // TODO: function for initializing the two servers
    // and make them ready to accept connections

    /* main loop */
    while (1) {
        get_doors_input(ListenSocketDoors);
        if (all_doors_state == SOME_OPENED)
            get_passengers_input(ListenSocketPassengers);

        if (some_condition)
            break;
    }

    /* cleanup the two servers: destroy sockets, etc. */
    // TODO

    return 0;
}

C'est une sorte de machine à états finis. Une façon simple de les mettre en place, en C, est l'utilisation des enum, et de fonctions qui s'occupent d'affecter les états en fonction des inputs, de gérer les transitions d'un état à un autre et les actions à exécuter selon les états courants, ces fonctions utilisant typiquement des switch/case.

Dal
[Dal]
Messages postés
5099
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mai 2019
937 -
tu voudras aussi éviter que les appels à accept() ne bloquent l'exécution de la boucle, par exemple en utilisant select() pour tester le socket avec un timeout

tu as un exemple là : https://www.installsetupconfig.com/win32programming/windowsocketwinsock214_12.html

ou en utilisant des sockets Windows non bloquants,

une autre façon est aussi de lancer les serveurs dans des threads.
emmy_2019
Messages postés
38
Date d'inscription
mardi 23 avril 2019
Statut
Membre
Dernière intervention
17 mai 2019
-
Si j'ai bien compris ave Init server:
j'ai fait ce bout de code , est-ce que cela que vous voulez avoir ?
SOCKET init_door(SOCKET AcceptDoorSocket)
{
	WSADATA wsaData;
    SOCKET ListenSocket;
	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

	  if (iResult != NO_ERROR)

		LOG_INFO("Server: Error at WSAStartup().\n");

	  else

		LOG_INFO("Server: WSAStartup() is OK.\n");






	  // The sockaddr_in structure specifies the address family,

	  // IP address, and port for the socket that is being bound.


	  service.sin_family = AF_INET;

	  service.sin_addr.s_addr = inet_addr("192.168.0.95");

	  service.sin_port = htons(8008);


	  
	  // Create a SOCKET for listening for

	  // incoming connection requests.

	  ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	  if (ListenSocket == INVALID_SOCKET)

	  {

		LOG_INFO("Server: Error at socket(): %ld\n", WSAGetLastError());

		WSACleanup();

		//return 0;

	  }

	  else

		LOG_INFO("Server: socket() is OK.\n");


	  if (bind(ListenSocket, (SOCKADDR*) &service,	sizeof(service)) == SOCKET_ERROR)

	  {

		LOG_INFO("Server: bind() failed.\n");

		WSACleanup();

		//return -1;

	  }

	  else

		LOG_INFO("Server: bind() is OK.\n");



	   // Listen for incoming connection requests on the created socket
	  if (listen(ListenSocket, 10) == SOCKET_ERROR)
	  {
		LOG_INFO("Server: Error listening on socket.\n");
		WSACleanup();
		//return -1;
	  }

	  else

		LOG_INFO("Server: listen() is OK.\n");
	 AcceptDoorSocket = accept(ListenSocket, (struct sockaddr*)&IRMAClient, &iIRMAClientLen))
	 if (AcceptSocket == INVALID_SOCKET)

	{

		LOG_INFO("Server: accept() error %d\n", WSAGetLastError());
		WSACleanup();
	}
	else
		 LOG_INFO("Server: accept() is OK.\n");

		 LOG_INFO("Server: accepted connection from %s, port %d\n", inet_ntoa(IRMAClient.sin_addr), htons(IRMAClient.sin_port)) ;
	 
		 return AcceptDoorSocket;
    
}
[Dal]
Messages postés
5099
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mai 2019
937 -
Tu as besoin d'appeler
WSAStartup()
une seule fois dans ton code.

Tu vas créer un
ListenSocket
et appeler
bind()
et
listen()
avec celui-ci pour chaque serveur, et ce une seule fois par serveur.

Ces étapes terminent la mise en place de tes deux serveurs.

Ce qui doit fonctionner dans ta boucle, ce sont les
accept()
pour tes 2 serveurs, que tu vas lancer différemment selon l'état des portes comme montré dans le code indicatif que j'ai écris (et qui visait juste à te montrer comment organiser l'exécution des différentes parties du code selon un état).

Une fois sorti de la boucle principale lorsque l'événement
some_condition
se produit, tu fermes les sockets de tes serveurs et fais
WSACleanup()
une seule fois dans ton code.

Lis aussi mon message précédent, que tu n'as peut-être pas vu car tu postais ton message ci-dessus à la même minute : https://www.commentcamarche.net/forum/affich-36000852-remplir-les-donnees-recues-server-socket-tcp#3
emmy_2019
Messages postés
38
Date d'inscription
mardi 23 avril 2019
Statut
Membre
Dernière intervention
17 mai 2019
-
Merci beaucoup Dal,

je vais voir le select(). C'est vrai je n'ai pas lu ton message de select()

voilà ce que j'ai fait pour init servers:
 iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

   if (iResult != NO_ERROR)

  LOG_INFO("Server: Error at WSAStartup().\n");

   else

  LOG_INFO("Server: WSAStartup() is OK.\n");
 

   // Door Socket

   service.sin_family = AF_INET;

   service.sin_addr.s_addr = inet_addr("192.168.0.95");

   service.sin_port = htons(8008);
     // Create a SOCKET for listening for

   // incoming connection requests.

   ListenDoorSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

   if (ListenDoorSocket == INVALID_SOCKET)

   {

  LOG_INFO("Server: Error at socket(): %ld\n", WSAGetLastError());

  WSACleanup();

  //return 0;

   }

   else

  LOG_INFO("Server: socket() is OK.\n");


   if (bind(ListenDoorSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR)

   {

  LOG_INFO("Server: bind() failed.\n");

  WSACleanup();

  //return -1;

   }

   else

  LOG_INFO("Server: bind() is OK.\n");



    // Listen for incoming connection requests on the created socket
   if (listen(ListenDoorSocket, 10) == SOCKET_ERROR)
   {
  LOG_INFO("Server: Error listening on socket.\n");
  WSACleanup();
  //return -1;
   }

   else

  LOG_INFO("Server: listen() is OK.\n");

   // Passager Socket

     service.sin_family = AF_INET;

   service.sin_addr.s_addr = inet_addr("192.168.0.95");

   service.sin_port = htons(8080);
     // Create a SOCKET for listening for

   // incoming connection requests.

   ListenPassagerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

   if (ListenPassagerSocket == INVALID_SOCKET)

   {

  LOG_INFO("Server: Error at socket(): %ld\n", WSAGetLastError());

  WSACleanup();

  //return 0;

   }

   else

  LOG_INFO("Server: socket() is OK.\n");


   if (bind(ListenPassagerSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR)

   {

  LOG_INFO("Server: bind() failed.\n");

  WSACleanup();

  //return -1;

   }

   else

  LOG_INFO("Server: bind() is OK.\n");



    // Listen for incoming connection requests on the created socket
   if (listen(ListenPassagerSocket, 10) == SOCKET_ERROR)
   {
  LOG_INFO("Server: Error listening on socket.\n");
  WSACleanup();
  //return -1;
   }

   else

  LOG_INFO("Server: listen() is OK.\n");



Que pense-tu à propos ce que j'ai fait?
J'ai fait deux listenSocket( door et passager)
[Dal]
Messages postés
5099
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mai 2019
937 -
cela a l'air pas mal :-)
Commenter la réponse de [Dal]