Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[newbie][socket] send renvoie -1 et "no error"

3 réponses
Avatar
Cyril
J'ai un client et un serveur.
Après l'ouverture du socket, le serveur envoie un message avec send:

strcpy(buffer, "message envoyer par le serveur");
nombre_de_caractere=send(id_de_la_socket,buffer,strlen(buffer),0);

printf("%s / %d / %d /
%s",buffer,nombre_de_caractere,strlen(buffer),strerror(errno));

L'écran affiche : message envoyer par le serveur -1 / 30 / No error

Je ne comprends pas pourquoi ça renvoi -1 (c'est à dire d'après la doc
de send echec de la fonction )
Et je comprends encore moins pourquoi ça me met "no error" (alors que
c'est censé avoir échoué)

Le client reçoit

nombre_de_caractere=recv(id_de_la_socket,buffer,1505,0);
buffer[nombre_de_caractere]=0;
MessageBox(NULL,buffer, "reçu", 0);

Et là je reçoit un message vide !

J'utilise DEV-C++ IDE avec windows (c'est pour un programme qui devra
tourner sur un serveur windows 2003 et lancer un .bat puis le tuer en
cas d'échec au bout d'un certain temps)

Merci pour vos réponses

Cyril


Code complet du client et du serveur :
serveur***************************************

/*
Name: BadrServeur
Copyright: 2006 = 2007 par Badr Dib
Date: 11/08/06 18:47
Description: Serveur
Author: Badr Dib
Age:13 ans

*/

#include <stdio.h>
#include <pthread.h> // gestion des thread c'est à dire pour tuer le bat
// si il s'execute trop longtemps

#include <windows.h>
// ********************************************************
// Les includes
// ********************************************************
#include <winsock2.h> // pour les fonctions socket

#include <stdlib.h>
#include <windows.h>
// ********************************************************
// Les librairies
// ********************************************************
#pragma comment(lib,"ws2_32.lib")
#include <errno.h>


// ********************************************************
// Définition des variables
// ********************************************************
WSADATA initialisation_win32; // Variable permettant de récupérer la
structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des
fonctions utilisées
int tempo; // Variable temporaire de type int
int nombre_de_caractere; // Indique le nombre de caractères qui a été
reçu ou envoyé
char buffer[655]; // Tampon contenant les données reçues ou envoyées
char name[655];
char envoyer[655];
char commande[500];//commande dos à executer
SOCKET id_de_la_socket; // Identifiant de la socket
SOCKET id_de_la_nouvelle_socket; // Identifiant de la nouvelle socket
SOCKADDR_IN information_sur_la_source; // Déclaration de la structure
des informations lié à l'écoute
long nbsecond_attente; // Nombre de secondes pendant lequelles la
commande peut s'executer

pthread_t ta;
pthread_t tb;
PROCESS_INFORMATION pi;
static void *task_a (void *p_data)
{
// pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
// pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
int j;
// bon là le thread il attend 240 secondes et puis c'est tout
// ce thread n'a comme but que de regarder le temps passer


struct timespec ts = {nbsecond_attente};
pthread_delay_np( &ts );
puts ("Hello world A");
(void) p_data;
return NULL;
}


static void *task_b (void *p_data)
{
// pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
// pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);


// FILE* pFileConfig;
// ici je vais voir le fichier config.ini dans lequel je récupère
// une commande du type : ping -t 192.168.80.10 > test.txt
// pFileConfig = fopen("config.ini" ,"r" );
// fgets(commande,500,pFileConfig);

//***********ici c'est tous le bousin qui cré le nouveau processus et
lance un
// la commande contenu dans config.ini
STARTUPINFO si;
// PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
commande, // Command line.
NULL, // Process handle not
inheritable.
NULL, // Thread handle not inheritable.
TRUE, // Set handle inheritance to
FALSE.
0, // No creation flags.
NULL, // Use parent's environment
block.
NULL, // Use parent's starting
directory.
&si, // Pointer to STARTUPINFO
structure.
&pi ) // Pointer to
PROCESS_INFORMATION structure.
)


{
printf( "CreateProcess failed (%d).\n", GetLastError() );

}
else
{
// attente
WaitForSingleObject(pi.hProcess, INFINITE);

::CloseHandle(pi.hThread);
::CloseHandle(pi.hProcess);
}
//***********
printf( "tuer thread a (%d).\n", pthread_cancel (ta) ) ;
puts ("Hello world B");
(void) p_data;

return NULL;

}



int main (int argc, char* argv[])
{

int serveur = 0;

while (serveur < 999999999)
//while (1)
{
// ********************************************************
// Initialisation de Winsock
// ********************************************************
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);


// ********************************************************
// Ouverture d'une Socket
// ********************************************************
id_de_la_socket=socket(AF_INET,SOCK_STREAM,0);


// ********************************************************
// Activation de l'option permettant d'activer l'algorithme de Nagle
// ********************************************************
// tempo=1;
// erreur=setsockopt(id_de_la_socket,IPPROTO_TCP,TCP_NODELAY,(char
*)&tempo,sizeof(tempo));


// ********************************************************
// Lie la socket à une ip et un port d'écoute
// ********************************************************
information_sur_la_source.sin_family=AF_INET;
information_sur_la_source.sin_addr.s_addr=INADDR_ANY; // Ecoute
sur toutes les IP locales
information_sur_la_source.sin_port=htons(2016); // Ecoute sur le
port 33333
erreur=bind(id_de_la_socket,(struct
sockaddr*)&information_sur_la_source,sizeof(information_sur_la_source));


// ********************************************************
// Attente d'ouverture de session
// ********************************************************
erreur=99; // Initiation de erreur pour être sur que l'on va
rentrer dans la boucle
while(erreur!=0) // Boucle tant qu'une demande de session (SYN)
tcp n'a pas été reçu
erreur=listen(id_de_la_socket,1);
printf("\nlisten : OK");

// ********************************************************
// Acceptation de la demande d'ouverture de session
// ********************************************************
printf("\nAttente de la reception de demande d'ouverture de
session tcp (SYN)");
tempo=sizeof(information_sur_la_source); // Passe par une
variable afin d'utiliser un pointeur
id_de_la_nouvelle_socket=accept(id_de_la_socket,(struct
sockaddr*)&information_sur_la_source,&tempo);


// ********************************************************
// Reception des données
// ********************************************************


strcpy(buffer, "message envoyer par le serveur");

nombre_de_caractere=send(id_de_la_socket,buffer,strlen(buffer),0);

printf("%s / %d / %d /
%s",buffer,nombre_de_caractere, strlen(buffer),strerror(errno));




// ********************************************************
// Fermeture de la session TCP Correspondant à la commande connect()
// ********************************************************
erreur=shutdown(id_de_la_nouvelle_socket,2); // 2 signifie socket
d'émission et d'écoute


// ********************************************************
// Fermeture des deux socket correspondant à la commande socket()
et accept()
// ********************************************************
erreur=closesocket(id_de_la_nouvelle_socket);

erreur=closesocket(id_de_la_socket);


// ********************************************************
// Quitte proprement le winsock ouvert avec la commande WSAStartup
// ********************************************************
erreur=WSACleanup(); // A appeler autant de fois qu'il a été ouvert.
serveur++;
}


}



***********************************
***********************************
***********************************



Client*****************************

#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib,"ws2_32.lib")



LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int
nCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wc;

wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MaWinClass";

if(!RegisterClass(&wc)) return FALSE;

hwnd = CreateWindow("MaWinClass", "Badr", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
NULL, NULL,
hinstance, NULL);
if (!hwnd) return FALSE;

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);


while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
/******************************************************************************/

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{

static HWND hEdit = 0;
static HWND IP = 0;
static HWND Port = 0;
static HWND Name = 0;
static HWND Message = 0;
static HWND hwndButton_envoyer = 0;
static int cx, cy;

HDC hdc;
PAINTSTRUCT ps;
RECT rc;

switch (uMsg)
{
case WM_CREATE:
{





//Name
TEXTMETRIC tm;











//Boutton





hdc = GetDC (hwnd);
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
GetTextMetrics (hdc, &tm);
cx = 5 * 25;
cy = 10* 2;
ReleaseDC (hwnd, hdc);
/* Now create the button */
IP = CreateWindow (
"edit",/* Builtin button class */
"192.168.10.100",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
125, 25, cx, cy,
hwnd,/* Parent is this window. */
(HMENU) 1,/* Control ID: 1 */
((LPCREATESTRUCT) lParam)->hInstance,
NULL
);


hdc = GetDC (hwnd);
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
GetTextMetrics (hdc, &tm);
cx = 3 * 25;
cy = 10* 2;
ReleaseDC (hwnd, hdc);
/* Now create the button */
Port = CreateWindow (
"edit",/* Builtin button class */
"2016",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
125, 50, cx, cy,
hwnd,/* Parent is this window. */
(HMENU) 1,/* Control ID: 1 */
((LPCREATESTRUCT) lParam)->hInstance,
NULL
);



hdc = GetDC (hwnd);
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
GetTextMetrics (hdc, &tm);
cx = 4 * 25;
cy = 10* 2;
ReleaseDC (hwnd, hdc);
/* Now create the button */
Message = CreateWindow (
"edit",/* Builtin button class */
"Name",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
125, 75, cx, cy,
hwnd,/* Parent is this window. */
(HMENU) 1,/* Control ID: 1 */
((LPCREATESTRUCT) lParam)->hInstance,
NULL
);


hdc = GetDC (hwnd);
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
GetTextMetrics (hdc, &tm);
cx = 5 * 25;
cy = 10* 2;
ReleaseDC (hwnd, hdc);
/* Now create the button */
Name = CreateWindow (
"edit",/* Builtin button class */
"Message",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
125, 100, cx, cy,
hwnd,/* Parent is this window. */
(HMENU) 1,/* Control ID: 1 */
((LPCREATESTRUCT) lParam)->hInstance,
NULL
);


/* Now create the button */
hwndButton_envoyer = CreateWindow (
"Button",/* Builtin button class */
"Envoyer",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
125, 150, cx, cy,
hwnd,/* Parent is this window. */
(HMENU) 1,/* Control ID: 1 */
((LPCREATESTRUCT) lParam)->hInstance,
NULL
);


return 0;
break;

}


case WM_COMMAND:
if (LOWORD(wParam) == 1 &&
HIWORD(wParam) == BN_CLICKED &&
(HWND) lParam == hwndButton_envoyer)
{

// Reception des commandes

// Vérifie si on à cliquer sur le bouton


// Va contenir le texte du EditBox
char *ip = NULL;
char *port = NULL;
char *name = NULL;
char *message = NULL;
// Va contenir le nombres de caractères dans le
EditBox
unsigned int TextLen = 0;
unsigned int TextLen2 = 0;
unsigned int TextLen3 = 0;
unsigned int TextLen4 = 0;

// Récupère le nombres de caractères dans le
EditBox
TextLen = GetWindowTextLength(IP);
TextLen2 = GetWindowTextLength(Port);
TextLen3 = GetWindowTextLength(Name);
TextLen4 = GetWindowTextLength(Message);
// S'il n'est pas vide
if (TextLen)
{

// Alloue de la mémoire pour stocker le
texte
char ip[50];
char port[50];
char name[50];
char message[50];
// Récupère le texte
TextLen = GetWindowText(IP, ip, (TextLen
+ 1));
TextLen2 = GetWindowText(Port, port,
(TextLen2 + 1));
TextLen3 = GetWindowText(Name, name,
(TextLen3 + 1));
TextLen4 = GetWindowText(Message,
message, (TextLen4 + 1));
// Si aucune erreur et le EditBox
contient bien quelque chose
if (TextLen)
{
// Affiche le texte



}












WSADATA initialisation_win32; // Variable permettant de récupérer la
structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des
fonctions utilisées
int tempo; // Variable temporaire de type int
int nombre_de_caractere; // Indique le nombre de caractères qui a été
reçu ou envoyé
char buffer[655];
char NAME[655];
char MESSAGE[655];// Tampon contennant les données reçues ou envoyées
SOCKET id_de_la_socket; // Identifiant de la socket
SOCKADDR_IN information_sur_la_destination; // Déclaration de la
structure des informations lié au serveur



// ********************************************************
// Initialisation de Winsock
// ********************************************************
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);


// ********************************************************
// Ouverture d'une Socket
// ********************************************************
id_de_la_socket=socket(AF_INET,SOCK_STREAM,0);


// tempo=1;
// erreur=setsockopt(id_de_la_socket,IPPROTO_TCP,TCP_NODELAY,(char
*)&tempo,sizeof(tempo));



information_sur_la_destination.sin_family=AF_INET;
information_sur_la_destination.sin_addr.s_addr=inet_addr(ip); //
Indiquez l'adresse IP de votre serveur
information_sur_la_destination.sin_port=htons(2016); // Port
écouté du serveur (33333)
erreur=connect(id_de_la_socket,(struct
sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination));



// ********************************************************
// Envoi des données
// ********************************************************
// strcpy(buffer, message);
nombre_de_caractere=recv(id_de_la_socket,buffer,1505,0);
buffer[nombre_de_caractere]=0;
MessageBox(NULL,buffer, "reçu", 0);
// ********************************************************
// Fermeture de la session TCP Correspondant à la commande connect()
// ********************************************************
erreur=shutdown(id_de_la_socket,2); // 2 signifie socket
d'émission et d'écoute
// ********************************************************
// Fermeture de la socket correspondant à la commande socket()
// ********************************************************
erreur=closesocket(id_de_la_socket);

// ********************************************************
// Quitte proprement le winsock ouvert avec la commande WSAStartup
// ********************************************************
erreur=WSACleanup(); // A appeler autant de fois qu'il a été ouvert.
}
}
return 0;
case WM_DESTROY:

PostQuitMessage(0);
return 0;

default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}

3 réponses

Avatar
AlexSoft
tu auras plus de réponses sur un forum approprié...
Outre le fait que ton code semble plutot du C (je me suis arreté certes au
1er printf...) ton problème est plutot lié à la bibliothèque socket plutôt
qu'au langage C++.. Un autre forum serait + approprié . Essayes
fr.comp.os.ms-windows.programmation
Avatar
loufoque

Merci pour vos réponses


Ton code est du C, pas du C++.
Ton code est trop long, il faut isoler le problème.
Ton problème semble lié aux sockets POSIX, ce n'est donc pas le bon groupe.

Et puis ton code est pas terrible, même pour du C.
Essaie d'organiser ton code en parties indépendantes, de le factoriser, etc.

Avatar
Cyril
Problème résolu :

Dans ma fonction send je ne faisait pas référence au bon socket. Le
serveur ouvre un premier socket et réceptionne avec la commande accept
le socket du client c'est l'ID de ce 2° socket qu'il faut utiliser dans
la commande send.


Cyril