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)