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

Le
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).", GetLastError() );

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

::CloseHandle(pi.hThread);
::CloseHandle(pi.hProcess);
}
//***********
printf( "tuer thread a (%d).", 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_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; // 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("listen : OK");

// ********************************************************
// Acceptation de la demande d'ouverture de session
// ********************************************************
printf("Attente 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_socketcept(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_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);
}
}
Vos réponses
Trier par : date / pertinence
Harpo
Le #979413
Cyril wrote:

Code complet du client et du serveur :


Envoie plutôt le minimum vital qui plante parce que je ne suis pas sûr
que tout le monde a le temps de tout lire.

--
http://patrick.davalan.free.fr/

Eric Levenez
Le #979412
Le 12/10/06 17:25, dans
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é)


Poster un code c'est bien. Poster un code en C standard c'est mieux. Là ton
code est spécifique à Microsoft Windows. Je n'ai pas ce système, donc
impossible d'utiliser ou même de comprendre ton code. Tu aurais posté un
code pour Unix ou Linux, là aussi ce n'aurait pas été bien car ce groupe est
dédié au langage C standard.

Si send retourne -1 et ne positionne pas errno, c'est un bug du système, et
donc dans ton cas de Microsoft Windows. Demande donc sur un groupe dédié à
ce système si le bug est connu et comment le contourner.

Mais comme ton code à en tête le nom du programmeur, demandes lui la cause
du bug, cela ira peut-être plus vite.

--
Éric Lévénez -- Unix is not only an OS, it's a way of life.

gl
Le #979409
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 )
erreur dans l'envoie,le code erreur est indetermine. il est obtenu par:

int WSAGetLastError (void);
Ex:
in Err;
nombre_de_caractere=send(id_de_la_socket,buffer,strlen(buffer),0);
if(nombre_de_caractere==-1)
{
Err = WSAGetLastError();
//traitement erreur
}
printf("%s / %d / %d /
%s",buffer,nombre_de_caractere,strlen(buffer),strerror(errno));


Et je comprends encore moins pourquoi ça me met "no error" (alors que
c'est censé avoir échoué)


ce n'est pas "no error" mais "Numero erreur" avec errno indetermine

Cyril
Le #969865
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
Publicité
Poster une réponse
Anonyme