2016-04-10 3 views
-1

Я хочу отправить всем клиентам, подключенным на моем udp-сервере сообщение от одного клиента, и у меня есть эта ошибка: семейство адресов не поддерживается протоколом. Так что я искал решения в Интернете, но ничего не видел. Если вы можете помочь мне исправить эту ошибку, я был бы счастлив,Отправка сокетов всем клиентам udp c

С уважением

/* 
* 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); 

} 

редактировать: мой новейший УДП сервер и Java клиент (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); 

} 

Клиент:

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

какой вызов возвращает ошибку? – bmargulies

+0

Моя петля k (которая может отправить всем клиенту) –

+0

Циклы не возвращают ошибки. Системные вызовы возвращают ошибки. Что это было? Вы имеете в виду отправку * датаграмм * всем клиентам? – EJP

ответ

2

Ваш

struct sockaddr_in *clientaddr; 

выделяется как указатель на структуру sockaddr_in, но вы используете его как массив структур sockaddr_in в цикле:

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

Вы могли бы сделать clientaddr как массив указателей на 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

Здравствуйте, я скорректировал свой код с вашим, но теперь у меня есть эти ошибки: запрос для члена 'sin_addr' в чем-то не структуре или объединении hostp = gethostbyaddr ((const char *) & clientaddr [i] .sin_addr.s_addr , запрос для члена 'sin_addr' в чем-то не структуре или объединении sizeof (clientaddr [0] .sin_addr.s_addr), AF_INET); Как их удалить? –

+0

, так как clientaddr теперь представляет собой массив указателей на struct sockaddr_in, все места необходимо изменить к нему. – fluter

+0

, например. hostp = gethostbyaddr ((const char *) & (clientaddr [i] -> sin_addr.s_addr) и sizeof (clientaddr [0] -> sin_addr.s_addr) – fluter

Смежные вопросы