Probleme de sockets (en C)

Discutez d'informatique ici !
lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

Probleme de sockets (en C)

par lapras » 09 Juin 2008, 13:34

Bonjour,
je fais un pogramme en C qui a pour but de tester une connection entre deux ordinateurs : l'ordinateur A qui possede le programme serveur et l'ordinateur B qui a le programme client.
Voila le début de mon code : (je suis sur que tout le code est valide, pas besoin de le mettre en entier)
Client :
Code: Tout sélectionner
#if defined (WIN32)
#include
#elif defined (linux)
#include
#include
#include
#include
#include
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#endif
 
#include
#include
#define PORT 1723
 
 
 
int main(void)
{
    #if defined (WIN32)
        WSADATA WSAData;
        int erreur = WSAStartup(MAKEWORD(2,0), &WSAData);
    #else
        int erreur = 0;
    #endif
 
    SOCKET sock;
    SOCKADDR_IN sin;
    int sock_err;
    char buffer[32] = "";
 
    /* Si les sockets Windows fonctionnent */
    if(!erreur)
    {
        /* Création de la socket */
        sock = socket(AF_INET, SOCK_STREAM, 0);
 
        /* Configuration de la connexion */
        sin.sin_addr.s_addr = inet_addr("[COLOR=Red]IP ORDINTEUR A ICI[/COLOR]");
        sin.sin_family = AF_INET;
        sin.sin_port = htons(PORT);
 
        /* Si l'on a réussi à se connecter */
        if(connect(sock, (SOCKADDR *)&sin, sizeof(sin)) != SOCKET_ERROR)
        {



Serveur :
Code: Tout sélectionner
#if defined (WIN32)
#include
#elif defined (linux)
#include
#include
#include
#include
#include
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#endif
 
#include
#include
#define PORT 1723
 
 
 
int main(void)
{
    #if defined (WIN32)
        WSADATA WSAData;
        int erreur = WSAStartup(MAKEWORD(2,0), &WSAData);
    #else
        int erreur = 0;
    #endif
 
    SOCKET sock;
    SOCKADDR_IN sin;
    SOCKET csock;
    SOCKADDR_IN csin;
    char buffer[32] = "Bonjour !";
    int recsize = (int) sizeof csin;
    int sock_err;
 
    /* Si les sockets Windows fonctionnent */
    if(!erreur)
    {
        sock = socket(AF_INET, SOCK_STREAM, 0);
 
        /* Si la socket est valide */
        if(sock != INVALID_SOCKET)
        {
            printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
 
            /* Configuration */
            sin.sin_addr.s_addr    = htonl(INADDR_ANY);      /* Adresse IP automatique */
            sin.sin_family         = AF_INET;             /* Protocole familial (IP) */
            sin.sin_port           = htons(PORT);         /* Listage du port */
            sock_err = bind(sock, (SOCKADDR *) &sin, sizeof sin);
 
            /* Si la socket fonctionne */
            if(sock_err != SOCKET_ERROR)
            {
                /* Démarrage du listage (mode server) */
                sock_err = listen(sock, 5);
                printf("Listage du port %d...\n", PORT);
 
                /* Si la socket fonctionne */
                if(sock_err != SOCKET_ERROR)
                {
                    /* Attente pendant laquelle le client se connecte */
                    printf("Patientez pendant que le client se connecte sur le port %d...\n", PORT);       
 
                    csock = accept(sock, (SOCKADDR *) &csin, &recsize);
                    printf("Un client se connecte avec la socket %d de %s:%d\n", csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));


Bon le code marche en local (les deux programmes executés sur l'ordinateur A).
maintenant si je veux lancer serveur sur l'ordi A et client sur le B, je change l'ip pour le prgm client et je met l'ip internet de l'ordinateur A. Théoriquement, la connection devrait se faire. Mais ce n'est pas le cas : le prgm client ne se connecte pas au serveur. Pourtant je port est bien commun aux deux : j'ai choisi un port > 1500 et < 2^16 (pour avoir plus de chance qu'il soit libre). Quelle erreur ai je faite ?

merci d'avance
Lapras



Dominique Lefebvre
Membre Légendaire
Messages: 8005
Enregistré le: 03 Déc 2005, 12:00

par Dominique Lefebvre » 09 Juin 2008, 15:25

Salut lapras,

Voici un bout de code qui fonctionne pour initialiser une socket serveur:

[size=2][color=#008000]//** Ouverture de la socket Serveur

[/color][/size][size=2][color=#0000ff]if[/color][/size] ((sock_serv = socket(AF_INET, SOCK_STREAM, 0)) < 0)

WinsockException(
[size=2][color=#800000]"Erreur sur ouverture socket"[/color][/size]);

[size=2][color=#008000]//** Nommage de la socket Serveur

[/color][/size]memset(&ServAddr,0,[size=2][color=#0000ff]sizeof[/color][/size](ServAddr));

ServAddr.sin_family = AF_INET;

ServAddr.sin_addr.s_addr = inet_addr(servIP);

ServAddr.sin_port = htons(uiPort);

[size=2][color=#008000]//** Trace de la connexion si DEBUG

[/color][/size]sprintf(MessageErreur,[size=2][color=#800000]"Connexion sur %s:%d\n"[/color][/size],inet_ntoa(ServAddr.sin_addr),ServAddr.sin_port);

DebugTrace(MessageErreur);


lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

par lapras » 09 Juin 2008, 16:55

Salut Dominique,
c'est en gros ce que j'ai fait dans mon programme serveur.c
J'ai mis pour l'ip :
sin.sin_addr.s_addr = htonl(INADDR_ANY); /* Adresse IP automatique */
Et pour le client j'ai mis :
sin.sin_addr.s_addr = inet_addr("83.156.148.182");
c'est l' IP de l'ordinateur A (le mien) (le serveur client est executé sur l'ordinateur B)

Pourquoi la connection ne se fait elle pas ?

Dominique Lefebvre
Membre Légendaire
Messages: 8005
Enregistré le: 03 Déc 2005, 12:00

par Dominique Lefebvre » 09 Juin 2008, 17:48

Je ne comprends pas bien ton code. En principe sur le serveur, tu devrais un code de ce genre:

[size=2][color=#008000]//** Ouverture de la socket Serveur

[/color][/size][size=2][color=#0000ff]if[/color][/size] ((sock_serv = socket(AF_INET, SOCK_STREAM, 0)) < 0)

WinsockException(
[size=2][color=#800000]"Erreur sur ouverture socket"[/color][/size]);

[size=2][color=#008000]//** Nommage de la socket Serveur

[/color][/size]memset(&ServAddr,0,[size=2][color=#0000ff]sizeof[/color][/size](ServAddr));

ServAddr.sin_family = AF_INET;

ServAddr.sin_addr.s_addr = inet_addr(servIP);

ServAddr.sin_port = htons(uiPort);





[size=2][color=#008000]//** Bind de la socket Serveur sur l'adresse locale

[/color][/size][size=2][color=#0000ff]if[/color][/size] (bind(sock_serv,([size=2][color=#0000ff]struct[/color][/size] sockaddr *) &ServAddr, [size=2][color=#0000ff]sizeof[/color][/size](ServAddr)) < 0)

WinsockException(
[size=2][color=#800000]"Erreur sur bind socket"[/color][/size]);



[size=2][color=#008000]//** Attente de connexion entrante sur la socket Serveur

[/color][/size][size=2][color=#0000ff]if[/color][/size] (listen(sock_serv,MAXPENDING) < 0)

WinsockException(
[size=2][color=#800000]"Erreur sur listen socket"[/color][/size]);



printf(
[size=2][color=#800000]"Connexion sur %s port %d\n"[/color][/size],inet_ntoa(ServAddr.sin_addr),ServAddr.sin_port);

[size=2][color=#008000]//** le programme se met en attente de la première connexion du multiplexeur ou de l'automate

[/color][/size][size=2][color=#008000]//** lorsque la connexion est établie, il créé une socket de dialogue avec l'agent client

[/color][/size]ClntLen = [size=2][color=#0000ff]sizeof[/color][/size](ClntAddr);

[size=2][color=#0000ff]if[/color][/size] ((sock_client = accept(sock_serv,([size=2][color=#0000ff]struct[/color][/size] sockaddr *) &ClntAddr,&ClntLen)) < 0)

WinsockException(
[size=2][color=#800000]"Erreur sur accept"[/color][/size]);



[size=2][color=#008000]//** puis on boucle sur cette socket jusqu'à réception de FIN

[/color][/size]FinBoucleProg = VRAI;

[size=2][color=#0000ff]while[/color][/size] (FinBoucleProg)

{



[size=2][color=#008000]//** Lecture des données reçues sur la socket

[/color][/size][size=2][color=#0000ff]if[/color][/size] ((BytesRcvd = recv(sock_client,sCommand,RCVBUFSIZE,0)) < 0)

WinsockException(
[size=2][color=#800000]"Erreur de lecture"[/color][/size]);

[size=2][color=#008000]//** Mise en forme de l'ordre reçu

[/color][/size]sCommand[BytesRcvd] = [size=2][color=#800000]'\0'[/color][/size];

printf(
[size=2][color=#800000]"recu : %s\n"[/color][/size],sCommand);

[size=2][color=#008000]//** Création d'un thread pour traiter la commande reçue

[/color][/size]hThread = CreateThread(NULL, 0, DialogicProceed, sCommand, 0, &dwThreadId);

CloseHandle(hThread);

}
[size=2][color=#008000]// fin boucle principale du programme

[/color][/size]

[size=2][color=#008000]//** Fermeture de la socket et fin du programme

[/color][/size]closesocket(sock_client);

closesocket(sock_serv);

WSACleanup;

DebugTrace(
[size=2][color=#800000]"Fin du programme"[/color][/size]);


Tu dis que la connexion ne se fait pas, mais à quel niveau? Quelle erreur as-tu?

lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

par lapras » 09 Juin 2008, 18:03

c'est ce que j'ai fait :
on crée le socket :
Code: Tout sélectionner
sock = socket(AF_INET, SOCK_STREAM, 0);

On la configure (ip, port, famille de protocole) :
Code: Tout sélectionner
sin.sin_addr.s_addr    = htonl(INADDR_ANY);      /* Adresse IP automatique */
            sin.sin_family         = AF_INET;             /* Protocole familial (IP) */
            sin.sin_port           = htons(PORT);         /* Listage du port */
            sock_err = bind(sock, (SOCKADDR *) &sin, sizeof sin);


On listen sur le port :
Code: Tout sélectionner
sock_err = listen(sock, 5);

On établie une connection (accept(); ) :
Code: Tout sélectionner
csock = accept(sock, (SOCKADDR *) &csin, &recsize);
                    printf("Un client se connecte avec la socket %d de %s:%d\n", csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));


c'est ce que tu as fait dans ton code. je suis sur que mon code marche, car en local (client sur l'ordinateur A), mon script fonctionne parfaitement. (je peux envoyer des messages avec send(); )

Pour la connection quand client.exe tourne sur l'ordi B, c'est que le serveur ne détecte pas de csock (la fonction accept(); reste donc en attente)

Dominique Lefebvre
Membre Légendaire
Messages: 8005
Enregistré le: 03 Déc 2005, 12:00

par Dominique Lefebvre » 09 Juin 2008, 18:07

Je ne vois pas le bind avant le listen ...

PS : excuse moi j'ai mal lu !

lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

par lapras » 09 Juin 2008, 18:09

Le bind est dans la config. du socket :
Code: Tout sélectionner
sock_err = bind(sock, (SOCKADDR *) &sin, sizeof sin);

Dominique Lefebvre
Membre Légendaire
Messages: 8005
Enregistré le: 03 Déc 2005, 12:00

par Dominique Lefebvre » 09 Juin 2008, 18:11

lapras a écrit:Le bind est dans la config. du socket :
Code: Tout sélectionner
sock_err = bind(sock, (SOCKADDR *) &sin, sizeof sin);


Oui, j'avais lu rapidement...
Qu'est-ce qu'il te retourne comme erreur?

Dominique Lefebvre
Membre Légendaire
Messages: 8005
Enregistré le: 03 Déc 2005, 12:00

par Dominique Lefebvre » 09 Juin 2008, 18:13

As-tu essayé de lui passer l'adresse IP au lieu de la mettre en IP automatique?

lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

par lapras » 09 Juin 2008, 18:13

Je n'ai aucune erreur de ce coté. (j'ai des if pour vérifier si il y a une erreur)
le seul probleme c'est que la fonction accept(); ne détecte pas de client.
Oui j'ai essayé de mettre une IP (même plusieurs)
j'ai mis 127.0.0.1

Dominique Lefebvre
Membre Légendaire
Messages: 8005
Enregistré le: 03 Déc 2005, 12:00

par Dominique Lefebvre » 09 Juin 2008, 18:15

Tu n'aurais pas par hasard deux coupleurs réseaux sur ton PC?

lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

par lapras » 09 Juin 2008, 18:16

Un coupleur réseau ?
Je sens que je vais etre ammené a configurer mon routeur... Je n'y connais rien :triste:

Dominique Lefebvre
Membre Légendaire
Messages: 8005
Enregistré le: 03 Déc 2005, 12:00

par Dominique Lefebvre » 09 Juin 2008, 18:20

lapras a écrit:Un coupleur réseau ?
Je sens que je vais etre ammené a configurer mon routeur... Je n'y connais rien :triste:

coupleur réseau = carte réseau = NIC
Ton routeur est configuré en serveur DHCP?

lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

par lapras » 09 Juin 2008, 18:21

Dominique Lefebvre a écrit:coupleur réseau = carte réseau = NIC
Ton routeur est configuré en serveur DHCP?

Je n'en sais rien du tout, comment le savoir ?

Dominique Lefebvre
Membre Légendaire
Messages: 8005
Enregistré le: 03 Déc 2005, 12:00

par Dominique Lefebvre » 09 Juin 2008, 18:24

lapras a écrit:Je n'en sais rien du tout, comment le savoir ?

Regarde dans la configuration de ta pile IP sur ton PC (propriété sur ta connexion réseau) ...
Autre possibilité : le firewall Windows ou un autre est actif sur tes PC et empêche le port que tu as choisi de dialoguer. Pour voir, essayer de désactiver le firewall sur les deux PC.

lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

par lapras » 09 Juin 2008, 18:36

Le DHCP est activé. J'ai avast comme firewall, mais avast doit normalement m'avertir quand il bloque quelquechose ce qui n'est pas le cas ici. :marteau:

Dominique Lefebvre
Membre Légendaire
Messages: 8005
Enregistré le: 03 Déc 2005, 12:00

par Dominique Lefebvre » 09 Juin 2008, 18:43

lapras a écrit:Le DHCP est activé. J'ai avast comme firewall, mais avast doit normalement m'avertir quand il bloque quelquechose ce qui n'est pas le cas ici. :marteau:


Je ne sais pas trop ce que fait l'adressage Ip automatique de Winsock avec un serveur DHCP! A ta place, je chercherais les adresses IP de mes deux PC (avec Ipconfig) et j'utiliserais ces adresses pour paramétrer mes sockets...

lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

par lapras » 09 Juin 2008, 18:53

J'ai fais ipconfig dans cmd, et ca me sort :
Serveur DHCP : 192.168.1.1
alors je rentre cette ligne :
Code: Tout sélectionner
sin.sin_addr.s_addr    = inet_addr("192.168.1.1")

Mais la le serveur me renvoie une erreur :
sock_err = bind(sock, (SOCKADDR *) &sin, sizeof sin); renvoie SOCKET_ERROR
pourquoi ?

abcd22
Membre Complexe
Messages: 2426
Enregistré le: 13 Jan 2006, 14:36

par abcd22 » 09 Juin 2008, 19:19

192.168.1.1 c'est bien l'adresse IP de ton ordinateur ? Ce ne serait pas celle du routeur par hasard (c'est le routeur qui fait serveur DHCP a priori) ?

lapras
Membre Transcendant
Messages: 3664
Enregistré le: 01 Jan 2007, 12:00

par lapras » 09 Juin 2008, 19:23

Mon ordinateur (ordi A) est connecté par Wifi au modem de l'ordinateur B.
Comment puis je avoir l'ip de mon ordi ?

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite