SCR/AL1 - TOME III. Les librairies utilitaires
Les librairies s32wo et scr4wo contiennent toutes les fonctions utiles pour construire un serveur et un client TCP/IP à l'aide des sockets Windows.
Le serveur peut être mono-thread, multi-thread ou multi-process.
L'implémentation des sockets permet de communiquer à l'aide de nombreux protocoles différents, comme TCP-IP ou IPX. Dans cette implémentation, seul TCP-IP a été testé et implémenté.
Pour pouvoir exploiter ces fonctions, le système (WinNT, Win95 ou supérieur) doit disposer d'une couche TCP-IP. Seules les fonctions des sockets de base (winsock 1.1) sont exploitées.
Serveur TCP/IP
Pour construire un serveur, il suffit de définir une fonction serveur qui sera passée comme argument à la fonction de création du socket.
La fonction serveur sera automatiquement appelée et est uniquement chargée de lire, de traiter et d'écrire sur le socket. Elle ne doit effectuer aucune opération d'ouverture, de connexion ou de déconnexion : ces opérations sont gérées par la fonction de création de serveur.
Selon les paramètres passés, le serveur sera mono-thread, multi-thread ou multi-process.
Après une connexion, le serveur commence toujours par lire. Le client doit donc, après connexion, écrire sur le socket avant toute autre opération.
Client TCP-IP
Le client doit se connecter à un serveur identifié par une adresse IP ou un nom (résolu par un DNS). Ensuite, il écrit et lit sur le socket. Pour terminer, le client ferme sa connexion.
Fonction d'écriture
Les écritures sur le socket peuvent ou non être bufferisées. Les fonctions WSockB*() sont bufferisées. La variable WSOCK_BUFSIZE détermine la taille du buffer.
Pour des raisons de performance, il est toujours préférable d'utiliser la version bufferisée des fonctions d'écriture. En effet, le temps d'envoi d'un packet de 10 bytes est presque le même que celui d'un packet de 1000 bytes. De plus, dans le cas d'une conversation, l'envoi de deux packets successifs par le même côté du socket peut générer une perte très importante due à la nécessaire resynchronisation entre les deux partenaires.
Dans tous les cas, l'utilisation d'une fonction de lecture ou d'une fonction d'écriture non bufferisée envoie le contenu du buffer vers le socket.
Fonction de lecture
La bufferisation est gérée par la librairie de socket de Windows. Il n'y a donc pas lieu de choisir ici entre une version bufferisée ou non.
Il est à noter que la lecture peut ne pas retourner tous les bytes envoyés par le socket partenaire. Si on veut exactement lg bytes, il vaut mieux utiliser la fonction WSockReadLgBytes que WSockRead, cette dernière n'assurant pas la lecture de lg bytes.
Variables
Syntax
WSockStartServer(port, fn, subcmd, bThread, nqueue)
int port;
int (*fn)(int);
int nqueue;
char *subcmd;
int bThread;
Description
Fonction serveur. Démarre un socket côté serveur (STREAM).
Valeur retournée
Serveur multi-thread
FileServer(int sock)
{
int lg;
char buf[80];
while(1) {
lg = WSockReadString(sock, buf);
if(lg < 0) break;
if(strncmp(buf, "GET ", 4) == 0) {
FileCopy(sock, buf + 4);
break;
}
else if(buf[0] == 0) break;
else WSockPrintf(sock, "Error");
}
}
main()
{
int rc, port = 5000;
printf("\n*** Starting Server - pid=%d\n", getpid());
rc = WSockStartServer(port, FileServer, 0, 1, 4);
if(rc < 0) printf("Error %d.\n", rc);
exit(rc);
}
Serveur multi-process
Ce programme lancé sans argument démarre le serveur qui attend une connexion. Lors d'une connexion, il se lance avec comme paramètres -s et le numéro du socket créé. La fonction FileServer n'est utilisée que dans ce second cas.
FileServer()
{
...
}
main(argc, argv)
int argc;
char *argv[];
{
int rc, port = 5000;
char buf[120];
// Connexion établie, lancement de la fonction FileServer()
if(argc > 2 && strcmp(argv[1], "-s") == 0) {
printf("\n*** Connecting child for socket %d\n", atoi(argv[2]));
rc = WSockStartServerProc(atoi(argv[2]), FileServer);
exit(rc);
}
// Démarrage du serveur : attente de connexion
else {
printf("\n*** Starting Server - pid=%d\n", getpid());
sprintf(buf, "%s -s %%d", argv[0]);
rc = WSockStartServer(port, 0, buf, 0, 4);
if(rc < 0) {
printf("Error %d.\n", rc);
exit(rc);
}
}
}
Voir également
WSockStartServerProc(), WSockConnect()
File s_wsock.c
WSock1Register(int cltsock)
WSockBPrintf(cltsock, format, a1, a2, a3, a4, a5, a6, a7, a8, a9)
WSockBWrite(int sock, char *txt, int lg)
WSockBWriteRecord(int cltsock, char *txt, int lg)
WSockClose(int cltsock)
int WSockConnect(servername, port)
WSockFlush(int sock)
int WSockGetHost(char *name, int *ip)
int WSockGetIp(char *servername, int *ip)
WSockGetPeer(int cltsock, char *ip, char *name)
WSockPeek(int cltsock, char *txt, int lg)
WSockPrintf(cltsock, format, a1, a2, a3, a4, a5, a6, a7, a8, a9)
WSockRead(int cltsock, char *txt, int lg)
WSockReadLgBytes(int cltsock, char *txt, int lg)
WSockReadRecord(int cltsock, char *txt)
WSockReadRecordAlloc(int cltsock, char **txt)
WSockReadString(int cltsock, char *txt)
WSockStartServer(port, fn, subcmd, bThread, nqueue)
WSockStartServerProc(cltsock, fn)
WSockWrite(int cltsock, char *txt, int lg)
WSockWriteRecord(int cltsock, char *txt, int lg)
WSock1Register (file s_wsock.c:23)
Syntax
WSock1Register(int cltsock)
Description
WSockGetHost (file s_wsock.c:1024)
Syntax
int WSockGetHost(char *name, int *ip)
Description
Retourne le nom de la machine courante ainsi que son adresse IP.
Valeur retournée
WSockGetIp (file s_wsock.c:987)
Syntax
int WSockGetIp(char *servername, int *ip)
Description
Retourne l'adresse IP d'un host.
Valeur retournée
Syntax
WSockStartServerProc(cltsock, fn)
int cltsock;
int (*fn)(int);
Description
Fonction serveur. Branche sur un socket client pour lequel une connexion vient d'être créée. Un exemple peut être trouvé dans la fonction WSockStartServer()
Valeur retournée
Voir également
WSockStartServer()
Syntax
WSockGetPeer(int cltsock, char *ip, char *name)
Description
Fonction client et serveur. Retourne l'adresse IP et le nom de la machine partenaire dans la communication en court.
Valeur retournée
0 en cas de succès, code d'erreur sinon
Syntax
int WSockConnect(servername, port)
char *servername;
int port;
Description
Fonction client. Connecte à un serveur (STREAM).
Valeur retournée
Syntax
WSockClose(int cltsock)
Description
Fonction client. Ferme le socket client cltsock et désalloue l'environnement Windows Socket.
Ne pas utiliser dans le cas d'un serveur : le serveur se charge des opérations de début et de fin.
Syntax
WSockBWrite(int sock, char *txt, int lg)
Description
Fonction serveur et client. Bufferise les écritures. WSockFlush() vide le buffer.
La variable WSOCK_BUFSIZE permet de bufferiser les écritures.
Valeur retournée
Syntax
WSockBWriteRecord(int cltsock, char *txt, int lg)
Description
Fonction serveur et client. Bufferise un record précédé de sa longueur sur le socket cltsock. La longueur est d'abord envoyée dans les 4 premiers bytes, puis le record lui-même.
Valeur retournée
Syntax
WSockBPrintf(cltsock, format, a1, a2, a3, a4, a5, a6, a7, a8, a9)
int cltsock;
char *format;
char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9;
Description
Fonction serveur et client. Formatte et bufferise sur le socket décrit par cltsock.
Valeur retournée
Syntax
WSockFlush(int sock)
Description
Fonction serveur et client. Vide le buffer d'écriture.
La variable WSOCK_BUFSIZE définit la taille d'un buffer.
Valeur retournée
Syntax
WSockWrite(int cltsock, char *txt, int lg)
Description
Fonction serveur et client. Ecrit sur le socket décrit par cltsock.
La variable WSOCK_BUFSIZE permet de bufferiser les écritures.
Valeur retournée
Syntax
WSockWriteRecord(int cltsock, char *txt, int lg)
Description
Fonction serveur et client. Ecrit un record sur le socket cltsock. La longueur est d'abord envoyée dans les 4 premiers bytes, puis le record lui-même.
Valeur retournée
Syntax
WSockPrintf(cltsock, format, a1, a2, a3, a4, a5, a6, a7, a8, a9)
int cltsock;
char *format;
char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9;
Description
Fonction serveur et client. Ecrit sur le socket décrit par cltsock.
Valeur retournée
Syntax
WSockRead(int cltsock, char *txt, int lg)
Description
Fonction serveur et client. Lit maximum lg bytes sur le socket cltsock. Si le nombre de bytes lus est < lg, un 0 est ajouté après le dernier byte lu.
Valeur retournée
Syntax
WSockReadLgBytes(int cltsock, char *txt, int lg)
Description
Fonction serveur et client. Lit exactement lg bytes sur le socket cltsock.
Valeur retournée
Syntax
WSockReadRecord(int cltsock, char *txt)
Description
Fonction serveur et client. Lit un record dont la longueur est contenue dans les 4 premiers bytes sur socket cltsock.
Valeur retournée
Syntax
WSockReadRecordAlloc(int cltsock, char **txt)
Description
Fonction serveur et client. Lit et alloue un record dont la longueur est contenue dans les 4 premiers bytes sur socket cltsock.
Valeur retournée
Syntax
WSockReadString(int cltsock, char *txt)
Description
Fonction serveur et client. Lit un Zstring dans txt. Txt doit être de taille suffisante (en tout cas, min 20 bytes).
Valeur retournée
Syntax
WSockPeek(int cltsock, char *txt, int lg)
Description
Fonction serveur et client. Lit maximum lg le socket cltsock mais ne "consomme" pas les bytes. La prochaine lecture sur le socket contiendra toujours les bytes lus.
Valeur retournée
Indique s'il faut écrire chaque opération de lecture et d'écriture sur un socket dans le fichier debug.win.
Indique la taille du buffer pour les écriture sur les sockets. Par défaut, fixé à 4096.
Copyright © 1998-2015 Jean-Marc Paul and Bernard PAUL - Envoyez vos remarques ou commentaires à bernard@xon.be