Les sockets seulement en réseau ?

Signaler
Messages postés
55
Date d'inscription
dimanche 10 février 2002
Statut
Membre
Dernière intervention
20 décembre 2005
-
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
-
Bon, avant selon moi, les sockets pouvaient être utilisés par internet. Rien de plus logiques. Mais là j'ai programmé un squelette de chat avec les sockets et selon mes tests ca ne serait pas vrai. En effet, la connexion entre mon server et mon client ne se fait qu'avec une adresse ip locale. Par contre, ça m'étonne beaucoup. Je voudrais donc le savoir une fois pour toute.

Est-ce que winsock sert seulement à faire des connexions en réseau ?

20 réponses

Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,
Les sockets ne servent qu'a ca, etablir des connexions en reseau et "par internet".
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
salut ,
Les sockets peuvent fonctionner sur un même ordinateur ayant une seule et unique adresse IP. Mais il me semble qu'ils fonctionnent beaucoup mieux sur un réseau local ou internet. Je m'explique : Pour faire les premiers essais sur une application client/serveur, j'étais obligé de tester les 2 programmes sur un même ordinateur (celui utilisé pour la programmation en vc++). Au début, ça marchait parfaitement bien. Mais au fur et à mesure que le programme se compliquait, je commencais à avoir quelques problèmes de connexion. J'ai failli laisser tomber ce projet car je n'ai pas réussi à trouver la solution. Mais, quand je l'ai testé sur un vrai réseau local, j'ai eu la belle surprise de voir que tout fonctionnait merveilleusement bien. Puisque le but final est atteint, je n'ai pas cherché à comprendre pourquoi ça ne marchait pas aussi bien avec une seule adresse IP.
A++
Messages postés
55
Date d'inscription
dimanche 10 février 2002
Statut
Membre
Dernière intervention
20 décembre 2005

Merci pour vos réponses. Elles sont appréciées. Mais laissez moi spécifier ce que je voulais dire. C'est justement que tout marche quand je teste sur ma machine, et plus rien ne marche quand je pars dune autre machine. Je recoit une erreur 10061, cest a dire connection refused. Donc, c comme si mon server nexistait pas. Pourtant mon server ne me fait aucune erreur. Pouvez vous méclairer ?
Messages postés
55
Date d'inscription
dimanche 10 février 2002
Statut
Membre
Dernière intervention
20 décembre 2005

Au fait, si je fait le test je prend quelle adresse ip ? ou je la trouve ?
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,
Si tu teste avec un poste distant, il faut prendre l'ip internet du serveur. Pour trouver cette ip, la je peux pas vraiment t'aider, ca depend de la machine.
Messages postés
55
Date d'inscription
dimanche 10 février 2002
Statut
Membre
Dernière intervention
20 décembre 2005

ok mais c parce que quand jessai, même avec un autre programme que je nai pas programmé et qui est censé fonctionner, ca ne marche pas.
Messages postés
55
Date d'inscription
dimanche 10 février 2002
Statut
Membre
Dernière intervention
20 décembre 2005

Bon, pour vous simplifier la tâche au lieu de tourner en rond avec mes questions je vous propose mon code. Dites-moi ce qui cloche. Mon programme est compilé avec vc++. Et ne portez pas attenton aux commentaires, ils son utiles surtout pour moi :)

Server :

#include 
#include <winsock.h>
#include <string.h>
#include <stdio.h>

#define NETWORK_ERROR	-1
#define NETWORK_OK		0

void ReportError(int errorCode, const char *wichFunc)
{
char errorMsg[92]="\0";

sprintf(errorMsg,"Call to %s returned error %d",(char *)wichFunc,errorCode);

cout << errorMsg;
}

int main()
{

WORD SockVersion = MAKEWORD(1,1);

WSADATA wsaData;

int nret;

WSAStartup(SockVersion,&wsaData);

SOCKET ListeningSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if(ListeningSocket==INVALID_SOCKET)
{
nret=WSAGetLastError();
ReportError(nret,"socket()");

WSACleanup();
//return NETWORK_ERROR;

}

SOCKADDR_IN ServerInfo;

ServerInfo.sin_family=AF_INET;
ServerInfo.sin_addr.s_addr=INADDR_ANY;
ServerInfo.sin_port=htons(80);

nret=bind(ListeningSocket,(LPSOCKADDR)&ServerInfo, sizeof(struct sockaddr));

if(nret==SOCKET_ERROR)
{
nret=WSAGetLastError();
ReportError(nret,"bind()");

WSACleanup();
//return NETWORK_ERROR;
}

nret=listen(ListeningSocket, 10);

if(nret==SOCKET_ERROR)
{
nret=WSAGetLastError();
ReportError(nret,"listen()");

WSACleanup();
//return NETWORK_ERROR;
}

SOCKET Client;

Client=accept(ListeningSocket,NULL,NULL);

if(Client==INVALID_SOCKET)
{
nret=WSAGetLastError();
ReportError(nret,"accept()");

WSACleanup();
//return NETWORK_ERROR;
}

char Buffer[256]="\0";

strcpy(Buffer,"Allo\0");

while(1)
{
nret=send(Client,Buffer,strlen(Buffer),0);

if(nret==SOCKET_ERROR)
{
nret = WSAGetLastError();
ReportError(nret, "send()");

WSACleanup();
return NETWORK_ERROR;
}
}

cin >> Buffer;

closesocket(ListeningSocket);
closesocket(Client);

WSACleanup();
return NETWORK_OK;

}



Client :

#include 
#include <winsock.h>
#include <string.h>
#include <stdio.h>

#define NETWORK_ERROR	-1
#define NETWORK_OK		0

void ReportError(int errorCode, const char *wichFunc)
{
char errorMsg[92]="\0";

sprintf(errorMsg,"Call to %s returned error %d",(char *)wichFunc,errorCode);

cout << errorMsg;
}

int main()
{

WORD SockVersion = MAKEWORD(1,1);

WSADATA wsaData;

int nret;

WSAStartup(SockVersion,&wsaData);

SOCKET ListeningSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if(ListeningSocket==INVALID_SOCKET)
{
nret=WSAGetLastError();
ReportError(nret,"socket()");

WSACleanup();
//return NETWORK_ERROR;

}

SOCKADDR_IN ServerInfo;

ServerInfo.sin_family=AF_INET;
ServerInfo.sin_addr.s_addr=INADDR_ANY;
ServerInfo.sin_port=htons(80);

nret=bind(ListeningSocket,(LPSOCKADDR)&ServerInfo, sizeof(struct sockaddr));

if(nret==SOCKET_ERROR)
{
nret=WSAGetLastError();
ReportError(nret,"bind()");

WSACleanup();
//return NETWORK_ERROR;
}

nret=listen(ListeningSocket, 10);

if(nret==SOCKET_ERROR)
{
nret=WSAGetLastError();
ReportError(nret,"listen()");

WSACleanup();
//return NETWORK_ERROR;
}

SOCKET Client;

Client=accept(ListeningSocket,NULL,NULL);

if(Client==INVALID_SOCKET)
{
nret=WSAGetLastError();
ReportError(nret,"accept()");

WSACleanup();
//return NETWORK_ERROR;
}

char Buffer[256]="\0";

strcpy(Buffer,"Allo\0");

while(1)
{
nret=send(Client,Buffer,strlen(Buffer),0);

if(nret==SOCKET_ERROR)
{
nret = WSAGetLastError();
ReportError(nret, "send()");

WSACleanup();
return NETWORK_ERROR;
}
}

cin >> Buffer;

closesocket(ListeningSocket);
closesocket(Client);

WSACleanup();
return NETWORK_OK;

}



Merci beaucoup.
Messages postés
61
Date d'inscription
jeudi 31 janvier 2002
Statut
Membre
Dernière intervention
18 novembre 2005

Dans ta partie client, ce passage est plutôt étrange :
ServerInfo.sin_addr.s_addr=INADDR_ANY;


A cette endroit, tu dois définir l'adresse à laquelle le client doit se connecter. Tu dois donc spécifier une adresse IP valide.
Si tu travailles sur un seul ordi, tu peux utiliser "127.0.0.1", si tu es sur un autre ordi, tu dois y mettre l'adresse IP de l'ordi faisant tourner le serveur.
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,
En théorie INADDR_ANY sert a spécifier toutes les adresses que possede la machine (local, internet). Le code du serveur a l'air bon, mais je n'ai pas pu le tester (derriere un routeur).
Messages postés
55
Date d'inscription
dimanche 10 février 2002
Statut
Membre
Dernière intervention
20 décembre 2005

oh désolé ! C'est que j'ai mis le même code pour le server et le client sans faire exprès. Voici le vrai code du client :

#include 
#include <winsock.h>
#include <string.h>
#include <stdio.h>

#define NETWORK_ERROR	-1
#define NETWORK_OK		0

void ReportError(int errorCode, const char *wichFunc)
{
char errorMsg[92]="\0";

sprintf(errorMsg,"Call to %s returned error %d",(char *)wichFunc,errorCode);

cout << errorMsg;
}

int main()
{

WORD SockVersion = MAKEWORD(1,1);

WSADATA wsaData;

int nret;

WSAStartup(SockVersion,&wsaData);

LPHOSTENT hostEntry;
in_addr iaHost;

iaHost.s_addr =inet_addr("24.201.191.115");

hostEntry=gethostbyaddr((const char *)&iaHost, sizeof(struct in_addr), AF_INET);
//hostEntry=gethostbyname(IP);

if(!hostEntry)
{
nret=WSAGetLastError();
ReportError(nret,"gethostbyaddr()");

WSACleanup();
//return NETWORK_ERROR;
}

SOCKET Socket=socket(AF_INET,SOCK_STREAM,0);

if(Socket==INVALID_SOCKET)
{
nret=WSAGetLastError();
ReportError(nret,"socket()");

WSACleanup();
//return NETWORK_ERROR;

}

SOCKADDR_IN ServerInfo;

ServerInfo.sin_family=AF_INET;
ServerInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
ServerInfo.sin_port=htons(80);

nret=connect(Socket,(LPSOCKADDR)&ServerInfo,sizeof(struct sockaddr));

if(nret==SOCKET_ERROR)
{
nret = WSAGetLastError();
ReportError(nret, "connect()");

WSACleanup();
//return NETWORK_ERROR;
}

char Buffer[256]="\0";

//while(1)
//{
nret=recv(Socket,Buffer,sizeof(Buffer),0);
cout << Buffer;

if(nret==SOCKET_ERROR)
{
nret = WSAGetLastError();
ReportError(nret, "recv()");

WSACleanup();
//return NETWORK_ERROR;
}
//}

cin >> Buffer;

closesocket(Socket);

WSACleanup();
return NETWORK_OK;

}



Ce que je peux être bête.

Et aardman : selon ce tu dis, tu ne peux pas tester mon server à cause de ton routeur ? je ne comprends pas. Faudrait que tu mexpliques parce que jai moi aussi un routeur. Merci.
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,
En théorie INADDR_ANY sert a binder toutes les adresses ip du pc.
Si tu est sur un pc en direct sur internet, et que ton ip internet est 193.252.122.103 (exemple), ton server va pouvoir se binder sur cette adresse, et je pense que ca fonctionnera (car le code du serveur a l'air bon).

Maintenant si tu est sur un pc dans un reseau local, le reseau local relié au net via un routeur. Ton pc a une adresse ip locale, et ton routeur a une adresse ip internet (193.252.122.103 pour garder l'exemple).
Si tu bind sur ton adresse locale, pas de probleme, mais ton serveur ne sera visible que dans le reseau local.
Si tu bind sur 193.252.122.103, ca ne peut pas marcher, car 193.252.122.103 n'est pas une interface (ip valide) de ta machine.

Je précise que je suis pas expert en reseau et que je peux me tromper.
Mais bon ca m'a l'air logique, on ne peut établir des connexions avec les clients que lorsque ceux-ci cherchent a se connecter a ton ip.
Messages postés
55
Date d'inscription
dimanche 10 février 2002
Statut
Membre
Dernière intervention
20 décembre 2005

Ah d'accord je comprends. Ca confirme bien des choses. Cepdandant jai tenté de faire avec un de mes amis ( qui est évidemment chez lui et donc pas sur mon réseau ) en utilisant ladresse ip de mon serveur ( celle qui est dans le code du client ) et ca ne marchait pas. C'est à partir de là que je me suis posé des questions.
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,
Normalement si ton ami lance le serveur, l'adresse du serveur est donc l'adresse ip de ton ami.
Donc tu dois pouvoir t'y connecter en metant l'ip de ton ami dans le champ iaHost.s_addr du client.
Messages postés
55
Date d'inscription
dimanche 10 février 2002
Statut
Membre
Dernière intervention
20 décembre 2005

C'est exactement ce que jai fait sans résultats, malheureusement. J'ai essayé dans les deux sens, c'est-à-dire que jai essayé avec mon ami comme server et moi comme client, et vice versa. Je suis découragé mais merci tout de même pour l,aide que vous m'avez apportés.
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Salut ,
Je viens de tester ton programme serveur sur mon ordinateur :
Ca marche tres bien avec un autre programme client (le mien).
Je suis sur que le probleme est dans ton programme client.
Je vais le tester aussi si j'ai un peu de temps et je te dirai.
J'ai tout de meme une petite remarque sur ton code serveur :
la fonction send() renvoi une erreur (10054) apres chaque connexion et quitte le programme.C'est a dire que ton serveur n'accepte que la premiere connexion puis s'arrete. C'est normal car send() est appelée a l'infini dans la boucle while (). Pour resoudre ce petit probleme il suffit de mettre la foncion accept juste avant send() comme ceci:

while(1)
{
Client=accept(ListeningSocket,NULL,NULL);
if(Client==INVALID_SOCKET)
{
nret=WSAGetLastError();
ReportError(nret,"accept()");
WSACleanup();
//return NETWORK_ERROR;
}
nret=send(Client,Buffer,strlen(Buffer),0);
if(nret==SOCKET_ERROR)
{
nret = WSAGetLastError();
ReportError(nret, "send()");
WSACleanup();
return NETWORK_ERROR;
}
}

J'espere avoir aidé un peu. Dès que j'aurais fini de tester ton "client" je te dirai.
A++
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,
A propos du client:
Pourquoi ne pas avoir mis l'adresse ip directement dans
ServerInfo.sin_addr.s_addr ?

ServerInfo.sin_addr.s_addr = inet_addr("24.201.191.115");
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Salut,
Je suis tout a fait d'accord avec toi aardman.
Je pense que c'est la la cause du probleme. Pour etablir une connection directe entre un client et un serveur, on n'a pas forcement besoin des fonctions "gethostbyname()" ou "gethostbyaddr()" car elles ne servent qu'à recupérer le nom d'un ordinateur à partir de son IP ou l'inverse. Pour cela elles appellent une base de donnees locale ou celle d'un serveur DNS. Generalement celui du fournisseur d'acces internet (FAI).
Voici une version ameloirée du code que je vais tester:

#include 
#include <winsock.h>
#include <string.h>
#include <stdio.h>

#define NETWORK_ERROR -1
#define NETWORK_OK 0

void ReportError(int errorCode, const char *wichFunc)
{
char errorMsg[92]="\0";

sprintf(errorMsg,"Call to %s returned error %d",(char *)wichFunc,errorCode);

cout << errorMsg;
}

int main()
{

WORD SockVersion = MAKEWORD(1,1);

WSADATA wsaData;

int nret;

WSAStartup(SockVersion,&wsaData);

SOCKET Socket=socket(AF_INET,SOCK_STREAM,0);

if(Socket==INVALID_SOCKET)
{
nret=WSAGetLastError();
ReportError(nret,"socket()");

WSACleanup();
//return NETWORK_ERROR;

}

SOCKADDR_IN ServerInfo;

ServerInfo.sin_family=AF_INET;
ServerInfo.sin_addr =inet_addr("24.201.191.115");
ServerInfo.sin_port=htons(80);

nret=connect(Socket,(LPSOCKADDR)&ServerInfo,sizeof(struct sockaddr));

if(nret==SOCKET_ERROR)
{
nret = WSAGetLastError();
ReportError(nret, "connect()");

WSACleanup();
//return NETWORK_ERROR;
}

char Buffer[256]="\0";

//while(1)
//{
nret=recv(Socket,Buffer,sizeof(Buffer),0);
cout << Buffer;

if(nret==SOCKET_ERROR)
{
nret = WSAGetLastError();
ReportError(nret, "recv()");

WSACleanup();
//return NETWORK_ERROR;
}
//}

cin >> Buffer;

closesocket(Socket);

WSACleanup();
return NETWORK_OK;

}


Normalement ca doit marcher, mais on verra.
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Désolé il fallait ecrire :
ServerInfo.sin_addr.s_addr = inet_addr("24.201.191.115");


Je viens de le tester et CA MARCHE A MERVEILLE !

Je l'ai testé sur le reseau local et internet en appelant des serveur IRC. Il a suffit pour cela de mettre l'adresse IP du serveur IRC (193.110.95.1) et le numero du port (7000). Le programme recoit le message du serveur et l'affiche :
NOTICE AUTH :*** Looking up your hostname
Voila
Bonne suite de programmation!
Messages postés
55
Date d'inscription
dimanche 10 février 2002
Statut
Membre
Dernière intervention
20 décembre 2005

AH! Merci beaucoup... Je vais enfin pouvoir continuer mon projet. Je vous remerci grandement. Et cette manip que je faisais venait d'un tutorial que javais trouvé, voila ladresse : http://www.hal-pc.org/~johnnie2/winsock.html. Merci !
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Salut,
On est très content de savoir que ton problème est résolu. Ca fait toujours plaisir d'apprendre qu'on a été utile. Nous aussi il nous arrive d'avoir besoin d'aide de temps en temps, car l'univers de la programmation, surtout en c++, est très très vaste. Je dois dire aussi que grâce au site cppfrance (sources et forum) on fait beacoup de progrès. Grand merci à ses administrateurs et membres.
Je viens de visiter le site que tu nous a donné. Le tutoriel sur les winsocks est très bien fait, clair et donne de bonnes bases sur la programmation réseau. Mais il me semble qu'il est un peu ancien car il ne parle que de la version 1 des winsocks. Il serait préférable d'utiliser la version 2 (selon Microsoft) car en plus d'être entièrement compatible avec la version 1, elle propose d'autres fonctionnalités intéressantes.
Bonne programmation!
A++