[Résumé] Les programmeurs qui ont écrit des applications Winsock savent que l'écriture d'applications Winsock n'est en aucun cas une tâche facile. Vous ne devez pas gérer directement les API complexes de Winsock. Heureusement, Tclientsocket et Tserversocket dans Delphi4 encapsulent les API pertinentes dans Windows simplifient considérablement l'accès. à Winsock, nous permettant d'écrire des applications Winsock très facilement. Cet article explique comment écrire des applications Winsock à l'aide de Delphi à travers un exemple de lecture de l'écran d'un autre ordinateur du réseau local.
Quiconque a travaillé comme administrateur réseau sur un lieu de travail a peut-être vécu cette expérience. Comme il est ennuyeux de demander aux autres de fonctionner par « télécommande » par téléphone. De plus, je suis une personne paresseuse et je ne veux pas fuir. du haut de l'immeuble au rez-de-chaussée pour des affaires insignifiantes tous les jours, que faire ? Que diriez-vous d’écrire un programme qui lit l’écran d’un autre ordinateur ? C'est beaucoup plus intuitif. Pour communiquer au sein d'un réseau local, le meilleur choix est bien sûr d'utiliser Winsock. Les programmeurs qui ont écrit des applications Winsock savent que l'écriture d'applications Winsock n'est en aucun cas une tâche facile. Vous ne devez pas gérer directement les API complexes de Winsock. et Tserversocket dans Delphi4 encapsulent les API pertinentes dans Windows, ce qui simplifie grandement l'accès à Winsock et nous permet d'écrire des applications Winsock très facilement. Néanmoins, il est préférable d'avoir une certaine compréhension de Winsock. Je n'entrerai pas dans les détails ici. Vous pouvez trouver quelques livres et les lire vous-même.
Pour transmettre des données via le réseau, vous avez besoin d'au moins une paire de Sockets, l'un sur le client et l'autre sur le serveur. Une fois que le client et le socket du serveur établissent une connexion, ils peuvent communiquer entre eux. La connexion établie avec Socket. est établi sur TCP/Basé sur IP, il prend également en charge ipx/spx et d'autres protocoles associés. Dans Delphi, Tclientsocket et Tserversocket sont utilisés pour contrôler la connexion et la communication entre le client et le serveur Socket. Il est à noter que ces deux composants servent à gérer la connexion entre le serveur et le client. Ce ne sont pas des objets Socket eux-mêmes. Les objets Socket sont manipulés par TcustomwinSocket, comme Tclientwinsocket, Tserverclientwinsocket et Tserverwinsocket.
1. Composant Tclientsocket :
En ajoutant un Tclientsocket au formulaire, l'application devient un client Tcp/ip et Tclientsocket peut être utilisé pour manipuler l'objet Socket du client.
Pour établir une connexion à un serveur, vous spécifiez d'abord le serveur auquel vous souhaitez vous connecter. Il existe deux manières de spécifier le serveur. La première consiste à définir l'attribut Host pour spécifier le nom d'hôte du serveur, tel que http://www.inPRise.com ou le nom de la machine sur le réseau local. Cette méthode est intuitive, mais. cela nécessite une résolution du nom de domaine, qui sera légèrement plus rapide ; une autre méthode consiste à définir l'attribut Adress pour spécifier l'adresse IP de l'hôte, par exemple 130.0.1.1. Les deux méthodes sont équivalentes, mais si Host et Adress sont définis, Delphi utilisera uniquement la propriété Host.
Ensuite, vous devez spécifier le numéro de port pour vous connecter au serveur. L'une consiste à configurer le service pour qu'il utilise le numéro de port par défaut. L'autre consiste à définir directement le numéro de port parmi les numéros de port inférieurs à 1024. , beaucoup ont été alloués, comme FTP. Les ports sont le 20 et le 21, le port SMTP est le 25, le port du serveur WEB est le 80, etc. Afin d'éviter des conflits involontaires, il est recommandé, lors de la programmation de votre propre application, de le faire. Il est préférable de définir le port sur 1024 ou plus. Si Service et port sont définis en même temps, Delphi utilisera le port par défaut de Service.
Après avoir spécifié le serveur et le numéro de port, appelez la méthode open ou définissez l'attribut Active sur True. Le Socket du client fera une demande de connexion au Socket du serveur. Si le serveur est en état d'écoute à ce moment, il acceptera automatiquement la demande. demande d'établissement d'une connexion. Une fois connecté, son événement Onconnet est déclenché. Lorsque vous devez vous déconnecter, il vous suffit d'appeler la méthode close ou de définir l'attribut Active sur False. À ce moment, l'événement ondisconnet sera déclenché.
2. Composant Tserversocket :
Comme Tclientsocket, pour construire un serveur, il vous suffit de placer un composant Tserversock dans le Form.
L'objet socket côté serveur est plus compliqué à gérer. Lorsque le serveur est en état d'écoute, l'objet socket du serveur est manipulé par Tserversocket ; lorsque le client fait une demande, le serveur répond à la demande et établit une connexion. À ce stade, Tserverclientwinsocket est utilisé pour manipuler la connexion entre le serveur. Socket et le Socket du client.
Pour mettre le serveur en état d'écoute, vous devez d'abord spécifier le numéro de port. Bien entendu, il doit être le même que le numéro de port du client. Appelez ensuite la méthode open ou définissez la propriété Active sur True.
3.Communications :
Une fois la connexion entre le client et le serveur établie, la communication entre eux peut commencer. Delphi fournit plusieurs méthodes de communication pour Tserversocket et Tclientsocket est utilisé pour envoyer des informations textuelles, sendstream est utilisé pour envoyer des flux et SendBuf est utilisé pour envoyer des données d'une longueur spécifiée.
Il convient de noter que puisque la taille de tampon par défaut de Windows est de 4 Ko, lors de l'envoi d'informations de plus de 4 Ko, par exemple un flux binaire envoyé du serveur au client, il vous suffit d'utiliser Socket.SendStream() sur le serveur. , mais c'est différent sur le client. Cela déclenchera l'événement onread plusieurs fois, et Delphi ne définit pas d'événements tels que "onreadend". Par conséquent, le programmeur doit assembler lui-même les données lors de la réception. La méthode adoptée dans cet article consiste à envoyer d'abord la longueur du flux au client, puis à envoyer le flux. Le client écrit les données reçues dans un flux. Lorsque la longueur du flux est égale à la longueur renvoyée par le serveur, cela indique. que le client a fini de le recevoir. Pour le serveur, le flux utilisé comme paramètre sendstream sera "possédé" par le Socket. Lorsque l'objet Socket se terminera, il se terminera également. Ne le libérez pas vous-même, sinon une exception sera déclenchée.
De même, lorsque le texte envoyé est inférieur à 4K, par exemple lors de l'appel suivant dans le programme client
clientsocket1.Socket.SendText('gets');
clientsocket1.Socket.SendText('gets');
clientsocket1.Socket.SendText('gets');
Lorsque le serveur reçoit, des phénomènes tels que getsgets apparaissent. Cela peut être dû au fait que lorsque les données dans le tampon n'ont pas encore été envoyées, un nouveau texte est placé dans le tampon et l'ordinateur le traite comme le même lot de données à traiter. . Afin d'éviter que ce phénomène ne se produise, vous pouvez utiliser la méthode du « lancer la balle » d'avant en arrière dans le programme :
serveur client
clientsocket1.Socket.SendText('data1') socket.ReceiveText;
socket.sendtext('ok');
socket.receivetext;
clientsocket1.Socket.SendText('data2')
socket.ReceiveText;
socket.sendtext('end');
socket.receivetext;
Après avoir exécuté le programme serveur sur un autre ordinateur, entrez le nom de l'ordinateur dans la zone de texte de votre programme client, cliquez sur « Connecter » et cliquez sur « Obtenir une image ». Vous aurez une vue claire de l'écran de l'ordinateur de l'autre partie. Ce qui suit est le code source complet du programme. Ce programme peut fonctionner sous NT4.0, Win95, Win98 et LAN. Bien entendu, Windows doit avoir le protocole TCP/IP installé et une adresse IP attribuée ou spécifiée dynamiquement. adresse.
Si vous trouvez difficile de « commander » pendant que vous regardez, vous pouvez également analyser les événements du clavier et de la souris sur l'image1, puis les envoyer au serveur une fois que le serveur l'a reçu, il effectuera à nouveau la même opération, afin que vous ne le fassiez pas. Je n'ai pas à m'inquiéter. En utilisant Tclientsocket et Tserversocket de Delphi, vous pouvez également compléter le développement d'applications telles que la copie de fichiers, le chat en ligne, ICQ, etc. C'est très simple à mettre en œuvre. Vous pouvez librement utiliser votre imagination pour écrire des programmes plus attrayants.
Programme client :
unité principale ;
interface
utilise
Windows, messages, SysUtils, classes, graphiques, contrôles, formulaires, boîtes de dialogue,
ScktComp, StdCtrls, ExtCtrls, jpeg ;
taper
TForm1 = classe(TForm)
Panneau 1 : TPanel ;
ScrollBox1 : TScrollBox ;
Image1 : TImage ;
Bouton1 : TButton ;
Edit1 : TEdit ;
Bouton2 : TButton ;
ClientSocket1 : TClientSocket ;
Étiquette1 : TLabel ;
procédure Button1Click (Expéditeur : TObject);
procédure Button2Click (Expéditeur : TObject);
procédure ClientSocket1Connect(Expéditeur : TObject ;
Socket : TCustomWinSocket );
procédure ClientSocket1Error(Expéditeur : TObject ; Socket : TCustomWinSocket ;
ErrorEvent : TErrorEvent ; var ErrorCode : Integer );
procédure ClientSocket1Read (Expéditeur : TObject ; Socket : TCustomWinSocket) ;
procédure FormCreate(Expéditeur : TObject);
procédure FormClose (Expéditeur : TObject ; var Action : TCloseAction);
privé
{Déclarations privées}
publique
{Déclarations publiques}
fin;
var
Formulaire1 : TForm1 ;
c:entier long;
m:tflux mémoire ;
mise en œuvre
{$R *.DFM}
procédure TForm1.Button1Click(Expéditeur : TObject);
commencer
essayer
clientsocket1.Fermer ;
clientsocket1.Host:=edit1.text;
clientsocket1.Open; //Se connecter au serveur
sauf
showmessage(edit1.text+#13#10+'L'ordinateur n'est pas allumé ou le programme de service n'est pas installé');
fin;
fin;
procédure TForm1.Button2Click(Expéditeur : TObject);
commencer
clientsocket1.Socket.SendText('gets'); //Envoyer une requête pour informer le serveur qu'une image d'écran est nécessaire
fin;
procédure TForm1.ClientSocket1Connect(Expéditeur : TObject;
Socket : TCustomWinSocket );
commencer
caption:='Connectez-vous à'+edit1.text;
fin;
procédure TForm1.ClientSocket1Error(Expéditeur : TObject ;
Socket : TCustomWinSocket ; ErrorEvent : TErrorEvent ;
varErrorCode : entier );
commencer
caption:='Connexion'+edit1.text+'Échec';
showmessage(edit1.text+#13#10+'L'ordinateur n'est pas allumé ou le programme de service n'est pas installé');
code d'erreur :=0 ;
fin;
procédure TForm1.ClientSocket1Read(Expéditeur : TObject;
Socket : TCustomWinSocket );
var
buffer:array [0..10000] of byte ; //Définit le tampon de réception
longueur : entier ;
ll:chaîne;
b:tbitmap;
j:tjpegimage;
commencer
si c=0 alors //C est le nombre d'octets envoyés par le serveur. S'il vaut 0, cela signifie que la réception de l'image n'a pas encore commencé.
commencer
ll:=socket.ReceiveText;
c:=strtoint(ll); //Définit le nombre d'octets à recevoir
clientsocket1.Socket.SendText('okok'); //Notifier le serveur pour commencer à envoyer des images
fin sinon
commencer //Ce qui suit est la partie de réception des données d'image
len:=socket.ReceiveLength; //Lire la longueur du paquet
socket.ReceiveBuf(buffer,len); //Recevoir le paquet de données et le lire dans le tampon
m.Write(buffer,len); //Ajouter au flux M
if m.Size>=c then //Si la longueur du flux est supérieure au nombre d'octets à recevoir, la réception est terminée
commencer
m.Position:=0;
b:=tbitmap.Create;
j:=tjpegimage.Create;
essayer
j.LoadFromStream(m); //Lire les données du flux M dans l'objet image JPG J
b.Assign(j); //Convertir JPG en BMP
Image1.Picture.Bitmap.Assign(b); //Attribuer au composant image1
enfin //Ce qui suit est le travail de nettoyage
b.gratuit ;
j.gratuit;
clientsocket1.Active:=false;
clientsocket1.Active:=true;
m.Clair;
c:=0;
fin;
fin;
fin;
fin;
procédure TForm1.FormCreate(Expéditeur : TObject);
commencer
m:=tmemorystream.Create;
fin;
procédure TForm1.FormClose(Expéditeur : TObject ; var Action : TCloseAction) ;
commencer
m.gratuit;
ClientSocket1.Close ;
fin;
fin.
Programme serveur :
unité principale;
interface
utilise
Windows, messages, SysUtils, classes, graphiques, contrôles, formulaires, boîtes de dialogue,
ScktComp,jpeg;
taper
TForm1 = classe(TForm)
ServerSocket1 : TServerSocket ;
procédure ServerSocket1ClientRead(Expéditeur : TObject ;
Socket : TCustomWinSocket );
procédure FormCreate(Expéditeur : TObject);
privé
{Déclarations privées}
publique
{Déclarations publiques}
fin;
var
Formulaire1 : TForm1 ;
m1:tflux mémoire ;
mise en œuvre
{$R *.DFM}
procédure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket : TCustomWinSocket );
var
s,s1:chaîne;
bureau : toile ;
bitmap:tbitmap;
jpg:tjpegimage;
commencer
s:=socket.ReceiveText;
if s='gets' then //Le client émet une requête
commencer
bitmap:=tbitmap.Create;
jpg:=tjpegimage.Create;
desk:=tcanvas.Create; //Le code suivant permet d'obtenir l'image d'écran actuelle
desk.Handle:=getdc(hwnd_desktop);
m1:=tmemorystream.Create; //Initialiser le flux m1, après avoir envoyé le flux avec sendstream(m1),
//Il restera jusqu'à la fin de la conversation socket,
//Ne peut pas être libéré manuellement, sinon une exception sera déclenchée
avec bitmap faire
commencer
width:=écran.Width;
hauteur:=écran.Hauteur;
canvas.CopyRect(canvas.cliprect,bureau,bureau.cliprect);
fin;
jpg.Assign(bitmap); //Convertir l'image au format JPG
jpg.SaveToStream(m1); //Écrit l'image JPG dans le flux
jpg.gratuit;
m1.Position:=0;
s1:=inttostr(m1.size);
Socket.sendtext(s1); //Envoyer la taille de l'image
fin;
if s='okok' then //Le client est prêt à recevoir des images
commencer
m1.Position:=0;
Socket.SendStream(m1); //Envoyer une image JPG
fin;
fin;
procédure TForm1.FormCreate(Expéditeur : TObject);
commencer
ServerSocket1.open ;
fin;
fin.