Différence SDL net sockets

Un article de Remram44.


[modifier] Introduction

SDL_Net n'est qu'une surcouche pour l'utilisation des sockets : <sys/socket.h> sous unix/linux et winsock sous windows. SDL_Net est plus simple au début, mais moins puissante et moins rapide, et nécessite évidement la présence des libs SDL et SDL_Net. Si vous savez utiliser l'un des deux moyens de communiquer en réseau, les sockets ou SDL_Net, vous pouvez facilement apprendre le deuxième grâce au tableau ci-dessous (et des exemples qui devraient venir).

[modifier] Commandes de SDL_Net et des sockets

Commande Avec les sockets Avec SDL_Net
Headers // UNIX / Linux
#include <sys/types.h>   /* Types prédéfinis "c" */
#include <sys/socket.h>  /* Généralités sockets */
#include <sys/param.h>   /* Paramètres et limites système */
#include <netinet/in.h>  /* Spécifications socket internet */
#include <arpa/inet.h>   /* Adresses format "arpanet" */
#include <signal.h>      /* Signaux de communication */
#include <stdio.h>       /* I/O fichiers classiques */
#include <netdb.h>       /* Gestion network database */
#include <errno.h>       /* Erreurs système */
#include <unistd.h>      /* Je sais pas mais Lockless l'utilise */
#define closesocket close /*  Utiliser close() sous  linux */

// Windows

#include <winsock2.h>
#include <SDL/SDL.h>
#include <SDL/SDL_net.h>
Une adresse sockaddr ou sockaddr_in IPaddress
Création d'une socket
int sock = socket(AF_INET,SOCK_STREAM,0)
TCPsocket sock = SDLNet_TCP_Open(IPaddress* adresse);
Host to Network Byte Order htons() (2 octets)
htonl() (4 octets)
SDLNet_Write16(Uint16 value,void* area)
SDLNet_Write32(Uint32 value,void* area)
Création d'une adresse
sockaddr_in adresse; adresse.sin_family = AF_INET;
hostent* h = gethostbyname(hote); adresse.sin_addr = *((struct in_addr *)h->h_addr);
adresse.sin_port = htons(port); memset(&(adresse.sin_zero),0,8);
SDLNet_ResolveHost(IPaddress *address,char *host,Uint16 port)
Retour à l'IP
char* ip = inet_ntoa(in_addr) (retourne un tableau <acronym title="modifié à chaque appel de la fonction !">static</acronym>)
char* ip = SDLNet_ResolveIP(IPaddress *address)
Mettre une socket en écoute sur le port PORT
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT); // 0 pour n'importe quel port libre
my_addr.sin_addr.s_addr = INADDR_ANY;
bind(int sock,(struct sockaddr *)&my_addr,sizeof(struct sockaddr));
IPaddress adresse;
SDLNet_ResolveHost(&adresse,NULL,PORT);
Connexion
connect(sock,sockaddr* addr,sizeof(sockaddr))
TCPsocket sock = SDLNet_TCP_Open(IPaddress* adresse)
Ecoute d'un port
listen(sock,10) // 10 : max de connexions en attente
int len = sizeof(sockaddr); int sock_connected = accept(sock,sockaddr* adresse,&len) // Attention : len peut changer ici
// adresse devient l'adresse de l'appelant, et socket_connected est connectée à l'appelant
TCPsocket sock = SDLNet_TCP_Accept(TCPsocket* serveur)
Envoi des données
send(sock,void* donnees,int size,0)
SDLNet_TCP_Send(sock,void* donnees,int size)
Réception de données
recv(sock,void* donnees,int size,0)
SDLNet_TCP_Recv(sock,void* donnees,int size)
Fermeture de connexion
closesocket(sock) // close(sock) sous linux/unix
SDLNet_TCP_Close(sock)
Initialisation d'un groupe de sockets
fd_set fds; FD_ZERO(&fds);

...

Ajout d'une socket dans un groupe
FD_SET(sock,&fds);

...

Attente d'un changement dans un groupe
timeval tv; tv.tv_sec = SECONDES; tv.tv_usec = MICROSECONDES;
select(plus_haut_descripteur_de_fichier + 1,&fds,NULL,NULL,&tv);

...

[modifier] Note sur la portabilité

Pour rester portable avec socket/winsock, vous devez donner ces instructions au préprocesseur :

#ifdef __WIN32__
    #include <winsock2.h>
#else
    #include <sys/types.h>   /* Types prédéfinis "c" */
    #include <sys/socket.h>  /* Généralités sockets */
    #include <sys/param.h>   /* Paramètres et limites système */
    #include <netinet/in.h>  /* Spécifications socket internet */
    #include <arpa/inet.h>   /* Adresses format "arpanet" */
    #include <signal.h>      /* Signaux de communication */
    #include <stdio.h>       /* I/O fichiers classiques */
    #include <netdb.h>       /* Gestion network database */
    #include <errno.h>       /* Erreurs système */
    #include <unistd.h>      /* Je sais pas mais Lockless l'utilise */
 
    #define closesocket close
#endif

Et allez savoir pourquoi, winsock nécessite une initialisation :

// Procédure principale
int main()
{
    #ifdef __WIN32__
        // Initialisation de winsock (sous windows)
        WSADATA wsa;
        if(WSAStartup(MAKEWORD(1,1),&wsa)!= 0)
        {
            printf("main:%d : Impossible d'initialiser winsock !\n",__LINE__);
            exit(0);
        }
    #endif
 
    // ...

Enfin, vous devez linker la librairie libwsock32, via le paramètre suivant :

-lwsock32

(aucun commentaire actuellement)