Remplir les données reçues (server socket tcp)
Fermé
emmy_2019
Messages postés
59
Date d'inscription
mardi 23 avril 2019
Statut
Membre
Dernière intervention
16 septembre 2019
-
30 avril 2019 à 14:01
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 - 2 mai 2019 à 16:22
[Dal] Messages postés 6057 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 17 mars 2023 - 2 mai 2019 à 16:22
A voir également:
- Remplir les données reçues (server socket tcp)
- Tcp optimizer - Télécharger - Optimisation
- Scp server - Forum Jeux vidéo
- Udp vs tcp - Guide
- Error 2002 (hy000): can't connect to local mysql server through socket '/var/run/mysqld/mysqld.sock' (2) ✓ - Forum Linux / Unix
- Mot de passe administration freebox server ✓ - Forum Freebox
1 réponse
[Dal]
Messages postés
6057
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
17 mars 2023
1 043
2 mai 2019 à 11:37
2 mai 2019 à 11:37
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 :
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
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
Modifié le 2 mai 2019 à 12:03
J'ai pas compris ton get_doors_input(ListenSocketDoors); et get_passengers_input(ListenSocketPassengers);
le parmètre de la fonction est ListenSocketDoors retourné par la fonction listen?
car j'ai une fonction server door qui fait tout l'init, listen, accept et recv() :
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... cp = malloc(sizeof(Comptage) * 1024); while( (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)) ; while(1) { 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); } if (cp == NULL) return NULL; //LOG_INFO("Server: \n recvbuf = %s ", recvbuf); 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,"OpenState",Tag1,TagValue1); cp[count].ID = atoi(TagValue); //LOG_INFO("Server: \n Time = cp.ID \n\n recvbuf = %s ", recvbuf); sprintf(cp[count].Heure, TagValue1); //LOG_INFO("Server: \n Time = %s \n\n recvbuf = %s ", recvbuf); //memcpy(Count_Pass, Count_Pass, 1); LOG_INFO("Door: \n Time = %s \n ID= %d \nDoorState =% ", cp[count].Heure, cp[count].ID, cp[count].DoorState); send(AcceptSocket, reply, strlen(reply), 0); LOG_INFO("%s\n",reply); count++; } } return cp; }Aussi je ne vois pas l'idée de mettre l'init de deux serveurs en une seule fonction ?
2 mai 2019 à 12:10
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.
2 mai 2019 à 12:10
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; }Modifié le 2 mai 2019 à 13:02
Tu vas créer un et appeler et 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 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 se produit, tu fermes les sockets de tes serveurs et fais 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://forums.commentcamarche.net/forum/affich-36000852-remplir-les-donnees-recues-server-socket-tcp#3
Modifié le 2 mai 2019 à 15:32
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)