Bonjour,
Je viens vers vous car j'ai un petit problème concernant mon application qui tourne sous Win32 api avec Winsock(oui je l'avoue que c'est un peu vieux ,mais cela a l'avantage d'être portable partout)
Mon sujet traitant plusieurs choses j'espère le poster au bonne endroit, sinon merci de me dire ou le mettre.
Bref, j'ai un serveur multiclient qui doit pouvoir envoyer le message textuelle "marche" si je clique sur le bouton marche et arrêt si je clique sur le bouton arrêt ,mon multiclient sera mis sur un thread . Or mon programme marche 1 fois sur 2 : soit il plante avec une fenêtre me disant qu'il ne répond plus soit cela va se lancer , le message marche ou arrêt sera bien envoyer ,la communication entre les client et serveur se fera mais dès que je cliquerai sur arrêt rien ne se passera. Je sèche un peu la, j'ai pensé au début que c'était le "PeekMessage" (pour récupéré le message) qui était mal placé, je l'ai bougé ailleurs mais rien n'y fait.
Je ne pense pas que mon multiclient soit faux mais je peut me trompé.
Bref si quelqu'un pourrait me donner un piste sur mon problème ,je le remercierai beaucoup.
Je précise que mon IDE est code::Block 13.12
Voici le code du thread
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
struct thread1
{
    HWND hwnd1;
};
thread1 obj1;
UINT ThreadTemp (LPVOID lpvoid);
UINT ThreadTemp (LPVOID lpvoid)
{
    MSG msg;
 
    int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
    thread1 * temp = (thread1*)lpvoid;
    HWND hwnd = temp -> hwnd1;
    char buff[1000];
    HDC hdc = GetDC(hwnd);
 
    WSADATA wsa;
    SOCKET master , new_socket , client_socket[30] , s;
    struct sockaddr_in server, address;
    int max_clients = 30 , activity, addrlen, i, valread;
    char *message;
 
 
    //Memoire tampon
    int MAXRECV = 1024;
    //ensemble de descripteur de socket, pointeur optionel qui permet de vérifier les socket
    fd_set readfds;
    //1 extra for null character, string termination
 
    char *buffer;
    //Allocation dynamique
    buffer =  (char*) malloc((MAXRECV + 1) * sizeof(char));
    //initialise a 0 le nombre de client
    for(i = 0 ; i < 30; i++)
    {
        client_socket[i] = 0;
    }
 
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
 
        //    exit(EXIT_FAILURE);
    }
    if((master = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
    {
 
        exit(EXIT_FAILURE);
    }
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 3333 );
    //On lie le socket
    if( bind(master ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
    {
 
        exit(EXIT_FAILURE);
    }
    listen(master , 3);
    addrlen = sizeof(struct sockaddr_in);
 
    while(1)
    {
 
        FD_ZERO(&readfds);
 
 
        FD_SET(master, &readfds);
 
 
 
 
        for (  i = 0 ; i < max_clients ; i++)
        {
            s = client_socket[i];
            if(s > 0)
            {
                FD_SET( s , &readfds);
            }
        }
 
        //wait for an activity on any of the sockets, timeout is NULL , so wait indefinitely
 
        activity = select( 0 , &readfds , NULL , NULL , NULL);
 
 
        if ( activity == SOCKET_ERROR )
        {
 
            exit(EXIT_FAILURE);
        }
 
        //If something happened on the master socket , then its an incoming connection
 
        if (FD_ISSET(master , &readfds)) //FD_ISSET = Returns a non-zero value if the bit for the file descriptor fd is set in the file descriptor set pointed to by fdset, and 0 otherwise.
        {
 
 
            if ((new_socket = accept(master , (struct sockaddr *)&address, (int *)&addrlen))<0)
            {
 
                exit(EXIT_FAILURE);
            }
 
 
 
 
 
 
            for (i = 0; i < max_clients; i++)
            {
                if (client_socket[i] == 0)
                {
                    client_socket[i] = new_socket;
 
                    break;
                }
 
            }
 
 
        }
 
        //Partie qui va géré les deconnexion
        for (i = 0; i < max_clients; i++)
 
        {
 
            s = client_socket[i];
 
            //if client present in read sockets
 
            if (FD_ISSET( s , &readfds)) //FD_ = fonction de select
            {
 
                getpeername(s , (struct sockaddr*)&address , (int*)&addrlen);
 
                if(PeekMessage(&msg, NULL, 0, 0,PM_REMOVE )!=0);
                {
                    message = (char*)(msg.wParam);
                    send(new_socket , message , strlen(message) , 0);
                }
 
 
 
                //Check if it was for closing , and also read the incoming message
                //recv does not place a null terminator at the end of the string (whilst printf %s assumes there is one).
 
                valread = recv( s , buffer, MAXRECV, 0);
 
                if( valread == SOCKET_ERROR)
                {
                    int error_code = WSAGetLastError();
                    if(error_code == WSAECONNRESET)
                    {
                        //Somebody disconnected , get his details and print
 
 
                        //Close the socket and mark as 0 in list for reuse
 
                        closesocket( s );
                        client_socket[i] = 0;
                    }
 
                }
                if ( valread == 0)
                {
                    //Somebody disconnected , get his details and print
 
                    //Close the socket and mark as 0 in list for reuse
                    closesocket( s );
                    client_socket[i] = 0;
                }
 
 
                else
                {
                    //add null character, if you want to use with printf/puts or other string handling functions
                    buffer[valread] = '\0';
                    strcpy(buffer,"recu");
                    send( s , buffer , valread , 0 );
                }
            }
        }
    }
 
 
//   WSACleanup();
 
 
 
 
    // TextOut(hdc,15,15,(LPCTSTR)buff,strlen(buff));
    Sleep(50);
    return 0;
}
Et voici le code pour les boutons

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
LRESULT CALLBACK procedureFenetrePrincipale(HWND fenetrePrincipale, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
    static HWND boutons[4] = {NULL};
    HANDLE g_Mutex;
    PAINTSTRUCT ps;
    HDC hdc;
    HANDLE TEMP,TENS;
    switch (message)
 
    {
 
    case WM_CREATE:
 
        boutons[0] = CreateWindow("BUTTON", "Marche", WS_CHILD | WS_VISIBLE,
 
                                  5, 50, 200, 30, fenetrePrincipale, (HMENU)B_Marche, instance, NULL);
 
        boutons[1] = CreateWindow("BUTTON", "Arret", WS_CHILD | WS_VISIBLE,
 
                                  5, 80, 200, 30, fenetrePrincipale, (HMENU)B_Arret, instance, NULL);
 
        boutons[2] = CreateWindow("BUTTON", "Historique", WS_CHILD | WS_VISIBLE,
 
                                  5, 120, 200, 30, fenetrePrincipale, (HMENU)B_Historique, instance, NULL);
 
        boutons[3] = CreateWindow("BUTTON", "Quitter", WS_CHILD | WS_VISIBLE,
 
                                  5, 160, 200, 30, fenetrePrincipale, (HMENU)B_Quitte, instance, NULL);
 
        SetMenu(fenetrePrincipale,LoadMenu(instance,"ID_MENU"));
 
        return 0;
    case WM_PAINT:
        hdc = BeginPaint(fenetrePrincipale, &ps);
        obj1.hwnd1 = fenetrePrincipale;
        TEMP = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadTemp,(LPVOID)&obj1,CREATE_SUSPENDED,&thread2ID);
        ResumeThread(TEMP);
 
        //  SetThreadPriority(TEMP,THREAD_PRIORITY_HIGHEST);
 
        TENS = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadTens,(LPVOID)&obj2,CREATE_SUSPENDED,NULL);
 
        ResumeThread(TENS);
 
        //    SetThreadPriority(TENS,THREAD_PRIORITY_LOWEST);
 
        obj2.hwnd2 = fenetrePrincipale;
 
 
        EndPaint(fenetrePrincipale, &ps);
        break;
 
    case WM_COMMAND:
 
        switch(LOWORD(wParam))
 
        {
 
        case B_Marche:
 
            //MessageBox(fenetrePrincipale, "MARCHE", "Vous avez cliquez sur Marche", MB_ICONINFORMATION);
            PostThreadMessage(thread2ID,UWM_SEND_MY_STRING,(WPARAM) marche,0);
            break;
 
 
        case B_Arret:
 
            //MessageBox(fenetrePrincipale, "ARRET", "Vous avez cliquez sur Marche", MB_ICONINFORMATION);
            PostThreadMessage(thread2ID,UWM_SEND_MY_STRING,(WPARAM) arret,0);
            break;
 
        case B_Apropos:
 
            DialogBox(instance,"Apropos",fenetrePrincipale,(DLGPROC)aPropos_procedure);
 
            break;
 
 
        case B_Quitte:
 
            SendMessage(fenetrePrincipale, WM_DESTROY, 0, 0);
            break;
 
 
        }
 
        return 0;
 
 
    case WM_DESTROY:
 
        PostQuitMessage(0);
 
        return 0;
 
 
    default:
 
        return DefWindowProc(fenetrePrincipale, message, wParam, lParam);
 
    }
    return 0;
Cordialement