2013-05-01 2 views
1

Je suis en train de développer une application C++ dans openSUSE 12.3 et l'une de ses parties est chargée d'envoyer des données à un périphérique via Socket (en LAN). J'utilise ce codeProgrammation de socket sous Linux en C++

int sockfd, portno, n; 
struct sockaddr_in serv_addr; 
struct hostent *printer;  
portno = 9100; 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if(sockfd < 0) error("ERROR opening socket\n"); 
printer = gethostbyname("100.0.69.23"); 
if(printer == NULL) error("No such device on 100.0.69.23\n"); 
//set bit set to zero 
bzero((char *) &serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
bcopy((char *) printer->h_addr, (char *) &serv_addr.sin_addr.s_addr, printer-  >h_length); 

serv_addr.sin_port = htons(portno); 

if(connect(sockfd, (struct sockaddr *) & serv_addr, sizeof(serv_addr)) < 0) 
    {error("ERROR connecting"); 
      return; 
    } 

n = write(sockfd, data, datalenght); 
if(n < 0) error("ERROR sending command to printer"); 
n = read(sockfd, buffer, 200); 

Je pense que le code est correct, mais la fonction de connexion renvoie -1 et semble ne pouvait pas se connecter au périphérique (imprimante). Ce code a été écrit dans openSUSE 11 et fonctionnait correctement et je pouvais envoyer/recevoir des données à l'appareil mais quand je le copiais/le collais sur un nouveau système (openSUSE 12.3), il me donnait un échec de connexion. Le résultat de ping sur l'adresse IP spécifique qui est utilisée indique que le périphérique est accessible via LAN

+0

combien d'octets envoyez-vous à l'imprimante? – suspectus

+0

Vous vérifiez pour 'printer' avant d'être initialisé, puis après. Ce n'est pas bon. –

+2

En outre, quelle est exactement l'erreur que 'connect()' renvoie? Il doit avoir 90% de la réponse à votre question. –

Répondre

1

Comme déjà mentionné, vous vérifiez printer == NULL avant de l'initialiser. Je pense que vous vouliez dire ce qui suit à la place:

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) error("ERROR opening socket\n"); 
printer = gethostbyname("100.0.69.23"); 
... 

également la structure du code semble indiquer que lorsque vous voulez envoyer une commande à l'imprimante connect(), write() puis read(), ce qui est correct si vous ne jamais envoi d'une commande, mais sous-optimale si vous envoyez plusieurs commandes. Dans ce dernier cas, vous voulez séparer le connect() du write() car il est assez cher de se connecter, donc vous ne voulez le faire qu'une seule fois.

+0

Vous avez raison, mais le problème est un autre problème en ce moment, actuellement je ne pouvais pas me connecter à l'appareil .Après avoir résolu le problème principal, je vais changer le code comme vous l'avez dit et séparer le connecter et écrire. et la valeur sockfd est supérieure à 0 lorsque la fonction de connexion échoue – Areff

2

Je pense que vous devriez considérer la possibilité que hostent retourné par la fonction gethostbyname puisse avoir la famille d'adresses AF_INET6 (auquel cas ce sera IPv6 au lieu de l'adresse IPv4).

http://linux.die.net/man/3/gethostbyname

Vous pouvez utiliser la fonction d'extension GNU fonction gethostbyname2 qui vous permettra de spécifier la famille d'adresses.

printer = gethostbyname2("100.0.69.23", AF_INET); 

Ou au contraire, vous pouvez utiliser la fonction getaddrinfo, en fonction gethostbyname est dite obsolète, par la documentation.