Comment créer un socket TCP connecter en utilisant C à un port prédéfini

StackOverflow https://stackoverflow.com/questions/204169

  •  03-07-2019
  •  | 
  •  

Question

J'ai une question très simple. Je veux tester si un port particulier est actuellement utilisé ou non. Pour cela, je veux lier un socket TCP au port. Si la connexion est refusée, cela signifie que le port est utilisé et sinon, le port est libre.

Quelqu'un peut-il me dire s'il vous plaît comment puis-je écrire le code du socket TCP en C? Je suis sur une plateforme Solaris.

Je sais que c'est très basique. Mais j'apprécie votre aide. Merci d'avance.

Était-ce utile?

La solution

L'appel à la fonction bind renverra -1 en cas d'erreur. Ceci inclut le cas où l'adresse est déjà utilisée.

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 12345

int main()
{
  struct sockaddr_in addr;
  int fd;

  fd = socket(AF_INET, SOCK_STREAM, 0);
  if(fd == -1)
  {
      printf("Error opening socket\n");
      return -1;
  }

  addr.sin_port = htons(PORT);
  addr.sin_addr.s_addr = 0;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_family = AF_INET;

  if(bind(fd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in) ) == -1)
  {
      printf("Error binding socket\n");
      return -1;
  }

  printf("Successfully bound to port %u\n", PORT);
}

Autres conseils

Cela dépend légèrement de ce que vous essayez de tester.

L'utilisation de bind () de la manière suggérée par joelc vous indiquera si le port est ouvert sur une interface de votre ordinateur. Bien que pour être minutieux, vous ne devez pas seulement vérifier la valeur de retour de bind () , mais également numéro d'erreur == EADDRINUSE .

c'est à dire. (modification du code de joelc)


if(bind(socket, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) == -1)
{
    if( errno == EADDRINUSE )
    {
        // handle port already open case
    }
    else
    {
        // handle other errors
    }
}

En changeant l'adresse utilisée dans la ligne: par exemple.


    sin.sin_addr.s_addr = inet_addr("192.168.1.1");

... vous pouvez vérifier si un port est disponible sur une interface spécifique.

Sachez cependant que ce n'est pas un test parfait pour l'état du port. Si un autre processus avait le port ouvert et était terminé avant de le fermer normalement (c'est-à-dire avant d'appeler close () sur le socket), vous obtiendrez généralement le même EADDRINUSE Erreur. (selon que l'option SO_REUSEADDR a été définie sur le socket)

(remarque: si votre application de test ne dispose pas de privilèges suffisants, vous ne pourrez pas lier () à aucun port inférieur à 1024)

Comme l'a suggéré Anonymous, vous pouvez également consulter netstat . Cela vous donnera toutes les informations que vous pouvez obtenir en appelant de manière répétée bind () beaucoup plus rapidement et sans aucun des effets secondaires (comme il n'est pas nécessaire qu'il soit réellement lié aux ports, ce qui les rendrait inutilisables pour tout autre processus). Il suffit d'appeler netstat -a --numeric-ports -t et d'analyser le résultat obtenu pour obtenir tout ce que vous recherchez.

Cependant, un commentaire sur la suggestion de moogs - appeler Telnet sur chaque port vous indiquera uniquement si un socket écoute sur ce port - et non si il est réellement ouvert.

Voulez-vous simplement tester si le port particulier est actuellement utilisé? (et n'avez pas vraiment besoin de faire un programme). Si tel est le cas, vous pouvez utiliser telnet:

  

port hôte telnet

Si la connexion échoue, elle n'est pas utilisée. S'il se connecte et attend votre entrée, il est en cours d'utilisation:)

Vous voudrez peut-être consulter le code source de netstat. Je pense qu’il existe également un netstat dans Solaris.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top