2016-04-10 7 views
-1

Ich möchte an alle Clients in meinem UDP-Server eine Nachricht von einem Client senden, und ich habe diesen Fehler: Adresse Familie nicht vom Protokoll unterstützt. Also suchte ich nach Lösungen im Internet, aber ich sah nichts. Wenn Sie uns helfen können, diesen Fehler zu korrigieren, würde ich mich freuen,Senden von Sockets an alle Clients udp c

Grüße

/* 
* UDP server 
*/ 

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

#define BUFSIZE 1024 

/* 
* write error 
*/ 
void error(char *msg) { 
    perror(msg); 
    exit(1); 
} 

int main(int argc, char **argv) { 
    int sockfd; /* socket */ 
    int portno; 
    int clientlen; 
    struct sockaddr_in serveraddr; 
    struct sockaddr_in *clientaddr; 
    struct hostent *hostp; 
    char buf[BUFSIZE]; 
    char *hostaddrp; 
    int optval; 
    int n; 
    int i=0; 

    if (argc != 2) { 
    fprintf(stderr, "missing arguments.", argv[0]); 
    exit(1); 
    } 
    portno = atoi(argv[1]); 


    sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    if (sockfd < 0) 
    error("error socket"); 

    optval = 1; 
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 
     (const void *)&optval , sizeof(int)); 

    /* 
    * create address server 
    */ 
    bzero((char *) &serveraddr, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    serveraddr.sin_port = htons(8080); 


    if (bind(sockfd, (struct sockaddr *) &serveraddr, 
     sizeof(serveraddr)) < 0) 
    error("error whie associating bind and socket"); 


    clientlen = sizeof(*clientaddr); 
    while (1) { 

    clientaddr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); 
    hostp = (struct hostent *)malloc(sizeof(struct hostent)); 
    int length = sizeof(*clientaddr)/sizeof(clientaddr[0]); 
    bzero(buf, BUFSIZE); 
    n = recvfrom(sockfd, buf, BUFSIZE, 0, 
      (struct sockaddr *) &clientaddr[i], &clientlen); 

    if (n < 0) 
     error("error recvfrom"); 


    hostp = gethostbyaddr((const char *)&clientaddr[i].sin_addr.s_addr, 
       sizeof(clientaddr[0].sin_addr.s_addr), AF_INET); 
    if (hostp == NULL) 
     error("error gethostbyaddr"); 
    hostaddrp = inet_ntoa(clientaddr[i].sin_addr); 
    if (hostaddrp == NULL) 
     error("error inet_ntoa\n"); 
    printf("server received datagram from: %s (%s)\n", 
     hostp->h_name, hostaddrp); 
    printf("server received %d/%d octets: %s\n", strlen(buf), n, buf); 


    int k =0; 
    for(k;k<length;k++){ 
      n = sendto(sockfd, buf, strlen(buf), 0, 
      (struct sockaddr *) &clientaddr[k], clientlen); 
      if (n < 0) 
       error("error sendto");  
    } 
    i++;   
    } 
    close(sockfd); 

} 

edit: mein neuester udp-Server und Java-Client (ihmgui):

/* 
* Serveur en UDP 
*/ 

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

#define BUFSIZE 1024 
#define MAX_CLIENTS 1000 

/* 
* écrire une erreur 
*/ 
void error(char *msg) { 
    perror(msg); 
    exit(1); 
} 

int main(int argc, char **argv) { 
    int sockfd; /* socket */ 
    int portno; /* port à écouter */ 
    int clientlen; /* taille de l'adresse ip du client */ 
    struct sockaddr_in serveraddr; /* adresse serveur */ 
    struct sockaddr_in *clientaddr[MAX_CLIENTS]; /* adresse client */ 
    struct hostent *hostp; /* info de l'hôte client */ 
    char buf[BUFSIZE]; /* message du buffer */ 
    char *hostaddrp; /* pour lire les points de l'adresse ip */ 
    int optval; /* valeur pour setsockopt */ 
    int n; /* taille du message en octet*/ 
    int i=0; 
    int length = 0; 
    /* 
    * on vérifie si l'utilisateur à bien définit un port en parametre 
    */ 
    if (argc != 2) { 
    fprintf(stderr, "vous avez oublier de mettre un port en argument.", argv[0]); 
    exit(1); 
    } 
    portno = atoi(argv[1]); 

    /* 
    * socket: créer un socket parent 
    */ 
    sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    if (sockfd < 0) 
    error("erreur lors de l'ouverture de la socket"); 

    optval = 1; 
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 
     (const void *)&optval , sizeof(int)); 

    /* 
    * créer l'adresse internet du serveur 
    */ 
    bzero((char *) &serveraddr, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    serveraddr.sin_port = htons(8080); 

    /* 
    * bind: associe les sockets parents au port défini 
    */ 
    if (bind(sockfd, (struct sockaddr *) &serveraddr, 
     sizeof(serveraddr)) < 0) 
    error("erreur lors de l'association des sockets et du port"); 

    /* 
    * boucle principale qui attend les datagram socket 
    */ 
    while (1) { 
     clientlen = sizeof(struct sockaddr_in); 
    /* 
    * recvfrom: reçoit un datagrame de type UDP d'un client 
    */ 
    clientaddr[i] = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); 
    hostp = (struct hostent *)malloc(sizeof(struct hostent)); 
    bzero(buf, BUFSIZE); 
    n = recvfrom(sockfd, buf, BUFSIZE, 0, 
      (struct sockaddr*)clientaddr, &clientlen); 

    if (n < 0) 
     error("erreur dans le recvfrom"); 

    /* 
    * gethostbyaddr: determine qui a envoyé le message 
    */ 
    hostp = gethostbyaddr((const char *)&clientaddr[i]->sin_addr.s_addr, 
       sizeof(clientaddr[i]->sin_addr.s_addr), AF_INET); 
    if (hostp == NULL) 
     error("erreur sur gethostbyaddr"); 
    hostaddrp = inet_ntoa(clientaddr[i]->sin_addr); 
    if (hostaddrp == NULL) 
     error("erreur sur inet_ntoa\n"); 
    printf("le serveur a recu un datagram de: %s (%s)\n", 
     hostp->h_name, hostaddrp); 
    printf("le serveur a recu %d/%d octets: %s\n", strlen(buf), n, buf); 

    /* 
    * sendto: réecrit à tout les clients ce qu'il a reçu 
    */ 
    int k =0; 
    length = i + 1; 
    for(k; k < length; k++) { 
     n = sendto(sockfd, buf, strlen(buf), 0, 
        (struct sockaddr *) clientaddr[k], clientlen); 
     if (n < 0) 
      error("error sendto"); 
    } 
    i++;   
    } 
    close(sockfd); 

} 

Auftraggeber:

import java.awt.*; 
import javax.swing.*; 
import javax.swing.JPanel; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.net.*; 
import java.io.*; 
import java.util.*; 

public class IHM extends JFrame implements ActionListener{ 
    private static String mess; 
    private Graphics g; 
    private JPanel dessin=new JPanel(); 
    private JPanel zoneBouton=new JPanel(); 
    private JButton carre = new JButton("Carre"); 
    private JButton ligne = new JButton("Ligne"); 
    private JButton rond = new JButton("Rond"); 
    private JButton refresh = new JButton("Refresh"); 
    private DatagramSocket ds; 
    private DatagramPacket dp; 
    public IHM(){ 
     this.setTitle("IHM reseau"); 
     this.setLayout(new BorderLayout()); 
     this.setSize(800,500); 
     this.setDefaultCloseOperation(this.EXIT_ON_CLOSE); 
     GridLayout gl = new GridLayout(4,1); 
     zoneBouton.setLayout(gl); 
     carre.addActionListener(this); 
     rond.addActionListener(this); 
     ligne.addActionListener(this); 
     refresh.addActionListener(this); 
     zoneBouton.add(carre, BorderLayout.WEST); 
     zoneBouton.add(rond, BorderLayout.WEST); 
     zoneBouton.add(ligne, BorderLayout.WEST); 
     zoneBouton.add(refresh, BorderLayout.WEST); 
     this.add(dessin, BorderLayout.CENTER); 
     this.add(zoneBouton, BorderLayout.EAST); 
     this.setVisible(true); 
    } 
    public void paintComponent(Graphics g) 
     { 
      this.g = dessin.getGraphics(); 
      if(mess.contains("1") || mess.contains("carre")) 
      { 
       g.drawRect(5, 40, 90, 55); 
       g.fillRect(100, 40, 90, 55); 
      } 
      if(mess.contains("2") || mess.contains("rond")) 
      { 
       g.setColor(Color.green); 
       g.drawOval(195, 100, 90, 55); 
       g.fillOval(290, 100, 90, 55); 

      } 
      if(mess.contains("3") || mess.contains("ligne")) 
      { 
       g.setColor(Color.BLUE); 
       g.drawLine(5, 30, 380, 30); 

      } 
      if(mess.contains("4") || mess.contains("refresh")) 
      { 
       repaint(); 

      } 
      this.mess = ""; 
      //super.paintComponent(g); 
      //super.paintComponent(g); 
    } 
    public void actionPerformed(ActionEvent e) 
    { 
     if(e.getSource().equals(this.carre)){ 
      String message1 = "1"; 
      try{ 
       this.ds = new DatagramSocket(); 
       DatagramPacket msg = new DatagramPacket(new byte[512], 512); 
       DatagramPacket envoi = new DatagramPacket(message1.getBytes(), 
       message1.length(),InetAddress.getByName("127.0.0.1"),8080); 
       ds.send(envoi); 
       this.dp = new DatagramPacket(new byte[512], 512); 
       ds.receive(dp); 
       this.mess = new String(dp.getData()); 
      } 
      catch(UnknownHostException i){} 
      catch(IOException i){} 
      message1 = ""; 
     } 
     if(e.getSource().equals(this.rond)){ 
      String message2 = "2"; 
      try{ 
       this.ds = new DatagramSocket(); 
       DatagramPacket msg = new DatagramPacket(new byte[512], 512); 
       DatagramPacket envoi = new DatagramPacket(message2.getBytes(), 
       message2.length(),InetAddress.getByName("127.0.0.1"),8080); 
       ds.send(envoi); 
       this.dp = new DatagramPacket(new byte[512], 512); 
       ds.receive(dp); 
       this.mess = new String(dp.getData()); 
      } 
      catch(UnknownHostException i){} 
      catch(IOException i){} 
      message2 = ""; 
     } 
     if(e.getSource().equals(this.ligne)){ 
      String message3 = "3"; 
      try{ 
       this.ds = new DatagramSocket(); 
       DatagramPacket msg = new DatagramPacket(new byte[512], 512); 
       DatagramPacket envoi = new DatagramPacket(message3.getBytes(), 
       message3.length(),InetAddress.getByName("127.0.0.1"),8080); 
       ds.send(envoi); 
       this.dp = new DatagramPacket(new byte[512], 512); 
       ds.receive(dp); 
       this.mess = new String(dp.getData()); 
      } 
      catch(UnknownHostException i){} 
      catch(IOException i){} 
      message3 = ""; 
     } 
     if(e.getSource().equals(this.refresh)){ 
      String message4 = "4"; 
      try{ 
       this.ds = new DatagramSocket(); 
       DatagramPacket msg = new DatagramPacket(new byte[512], 512); 
       DatagramPacket envoi = new DatagramPacket(message4.getBytes(), 
       message4.length(),InetAddress.getByName("127.0.0.1"),8888); 
       ds.send(envoi); 
       this.dp = new DatagramPacket(new byte[512], 512); 
       ds.receive(dp); 
       this.mess = new String(dp.getData()); 
      } 
      catch(UnknownHostException i){} 
      catch(IOException i){} 
      message4 = ""; 
     } 
     System.out.println(mess); 
     this.paintComponent(this.g); 
     validate(); 
    } 
     // Fonction principale 
     public static void main (String[] args) 
     { 
      new IHM(); 
     } 
} 
+0

Welcher Aufruf gibt den Fehler zurück? – bmargulies

+0

Meine Schleife k (die an alle Clients senden kann) –

+0

Loops geben keine Fehler zurück. Systemaufrufe geben Fehler zurück. Was war es? Meinst du das Senden von * Datagrammen * an alle Clients? – EJP

Antwort

2

Ihre

struct sockaddr_in *clientaddr; 

wird als Zeiger zugewiesen sockaddr_in auf struct, aber Sie es wie ein Array von struct sockaddr_in in der Schleife verwenden:

sendto(sockfd, buf, strlen(buf), 0, 
     (struct sockaddr *) &clientaddr[k], clientlen); 

Sie könnten clientaddr als ein Array von Zeigern machen sockaddr_in:

#define MAX_CLIENTS 1000 
struct sockaddr_in *clientaddr[MAX_CLIENTS]; 
// in main loop: 
clientaddr[i] = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); 
recvfrom(sockfd, buf, BUFSIZE, 0, 
     (struct sockaddr *)clientaddr[i], &clientlen); 

// send loop: 
int k = 0; 
length = i + 1; 
for(k; k < length; k++) { 
     n = sendto(sockfd, buf, strlen(buf), 0, 
     (struct sockaddr *) clientaddr[k], clientlen); 
     if (n < 0) 
      error("error sendto"); 
} 
+0

Hallo, ich habe meinen Code mit Ihrem korrigiert, aber jetzt habe ich diese Fehler: Anfrage für Mitglied 'sin_addr' in etwas nicht eine Struktur oder Union hostp = gethostbyaddr ((const char *) & clientaddr [i] .sin_addr.s_addr , Anfrage für Mitglied 'sin_addr' in etwas nicht eine Struktur oder Union sizeof (clientaddr [0] .sin_addr.s_addr), AF_INET); Wie kann ich sie entfernen? –

+0

da die clientaddr jetzt ein Array von Zeigern auf struct sockaddr_in ist, müssen alle Stellen in sie geändert werden. – fluter

+0

z.B. hostp = gethostbyaddr ((const char *) & (clientaddr [i] -> sin_addr.s_addr) und sizeof (clientaddr [0] -> sin_addr.s_addr) – fluter