将UDP数据包发送到2个客户端,只有一个接收

时间:2015-08-05 08:10:00

标签: c udp ethernet unix-socket

(抱歉我的英文...) 我正在开发一台PC和一组通过以太网连接的Zedboards之间的网络。我使用UDP协议,这是我的问题: - 我的所有卡和我的PC都正确连接到交换机并拥有自己的IP(PC为192.168.1.15,卡为11/12)。 - 当我尝试使用带有下面代码的unix套接字发送一个简单的数据包时,只收到最后一条消息(但似乎都是发送的)(加上,编译时没有错误或警告) - 如果我切换两个发送,它总是到达目的地的最后一个,因此它不是卡问题...

的main.c

#include "send_tool.h"

static int PORT;
static char LOCAL_ADDRESS[50]; 

static SOCKADDR_IN client_list[NB_CLIENTS];
static int uc_sock;

int main(int argc, char **argv)
{
char buffer[BUF_SIZE];

int actual;int i;
memset(buffer,0, sizeof(buffer));

SOCKADDR_IN csin = { 0 };

if(argc < 3)
{
    PORT = 2005;
    sprintf(LOCAL_ADDRESS, "192.168.1.15");
    printf("Valeurs de parametre forcees: %d\t%s\n", PORT, LOCAL_ADDRESS);
}
else
{
    PORT = atoi(argv[1]);
    sprintf(LOCAL_ADDRESS, argv[2]);
}
uc_sock = init_UC_connection(LOCAL_ADDRESS, PORT);

while(actual < NB_CLIENTS)
{
    read_UDP(uc_sock, &csin, buffer);
    if(!strncmp(buffer, "free:",5))
    {
        //add_client(client_list, csin);
        client_list[actual].sin_addr.s_addr = csin.sin_addr.s_addr;
        client_list[actual].sin_port = csin.sin_port;
        client_list[actual].sin_family = csin.sin_family;
        memcpy(client_list[actual].sin_zero, csin.sin_zero, 8);
        //sprintf(buffer, "salut");
        //write_UDP(uc_sock, &client_list[actual], buffer, strlen(buffer));
        actual++;
    }
}

printf("************************************\n");
printf("0: %s:%d/%d\n", inet_ntoa(client_list[0].sin_addr), ntohs(client_list[0].sin_port), client_list[0].sin_family);
printf("1: %s:%d/%d\n", inet_ntoa(client_list[1].sin_addr), ntohs(client_list[1].sin_port), client_list[1].sin_family);
printf("************************************\n");

sprintf(buffer, "au revoir");
write_UDP(uc_sock, &client_list[0], buffer, strlen(buffer));
write_UDP(uc_sock, &client_list[1], buffer, strlen(buffer));

memset(buffer, 0, sizeof(buffer));

while(read_UDP(uc_sock, &csin, buffer) > 0){}

close(uc_sock);
    return 0;
}

send_tool.h

/* STD LIBS */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>

//#include <sys/types.h>
//#include <sys/stat.h>

/* SOCKETS */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>

/* TIME */
#include <sys/timerfd.h>
#include <sys/time.h>

#include <pthread.h>
#include <semaphore.h>
#include <signal.h>

#define BUF_SIZE    60000
#define MULTICAST_ADDRESS "224.0.0.1"
#define  NB_CLIENTS 2

typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
typedef struct in_addr IN_ADDR;

int init_UC_connection(char LOCAL_ADDRESS[], int port);

void write_UDP(int sock, SOCKADDR_IN *sin, const char *buffer, size_t buff_len);
int read_UDP(int sock, SOCKADDR_IN *sin, char *buffer);

send_tool.c

#include "send_tool.h"

int init_UC_connection(char LOCAL_ADDRESS[], int port)
{
    /* UDP so SOCK_DGRAM */
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN sin = { 0 };
    struct timeval tv;
    tv.tv_sec = 3;
    tv.tv_usec = 0;

    if(sock == -1)
    {
        perror("socket()");
        exit(errno);
    }

    sin.sin_addr.s_addr = inet_addr(LOCAL_ADDRESS);
    sin.sin_port = htons(port);
    sin.sin_family = AF_INET;

    if(bind(sock,(SOCKADDR *)&sin, sizeof sin) == -1)
    {
        perror("bind()");
        exit(errno);
    }

    if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) {
        perror("Error");
    }

    return sock;
}

void write_UDP(int sock, SOCKADDR_IN *sin, const char *buffer, size_t buff_len)
{
    socklen_t sinsize = 16;//sizeof *sin;
    printf("sinsize : %d\n", sinsize);
    int n;
    size_t i;

    if((n=sendto(sock, buffer, buff_len, 0, (SOCKADDR *) sin, sinsize)) < 0)
    {
        perror("send()");
        exit(errno);
    }
    printf("envoi (sinsize = %d; n = %d)|%s| a %s:%d/%d termine \n", sinsize, n, buffer, inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), sin->sin_family);
}

int read_UDP(int sock, SOCKADDR_IN *sin, char *buffer)
{
    int n = 0;
    socklen_t sinsize = sizeof *sin;

    if((n = recvfrom(sock, buffer, BUF_SIZE - 1, 0, (SOCKADDR *) sin, &sinsize)) < 0)
    {
        perror("recvfrom()");
        exit(errno);
    }
    printf("recu (sinsize = %d; n = %d)|%s| depuis %s:%d/%d termine \n", sinsize, n, buffer, inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), sin->sin_family);

    return n;
}

client.c

#include "receive_tool.h"

static int PORT;
static char LOCAL_ADDRESS[50];

/* main function, launching the Server application*/
int main(int argc, char **argv)
{
    int uc_sock;

    char free_msg[30];
    memset(free_msg, 0, sizeof(free_msg));

    char buffer[60000];
    memset(buffer, 0, sizeof(buffer));

    if(argc < 3)
    {
        PORT = 2005;
        sprintf(LOCAL_ADDRESS, "192.168.1.12");
        //printf("Valeurs de parametre forcees: %d\t%s\n", PORT, LOCAL_ADDRESS);
    }
    else
    {
        PORT = atoi(argv[1]);
        sprintf(LOCAL_ADDRESS, argv[2]);
    }
    sprintf(free_msg, "free:%s", LOCAL_ADDRESS);

    SOCKADDR_IN server_sin = { 0 }, receive_sin = { 0 };
    server_sin.sin_addr.s_addr = inet_addr(SERVER_ADDRESS); // addresse multicast vers les serveurs
    server_sin.sin_family = AF_INET;
    server_sin.sin_port = htons(PORT);
    memset(&server_sin.sin_zero, 0, sizeof(server_sin.sin_zero));

    uc_sock = init_UC_connection(LOCAL_ADDRESS, PORT);

    write_UDP(uc_sock, &server_sin, free_msg);

    time_t chrono_begin;
    chrono_begin = time(NULL);
    chrono_begin+= 5;
    while(time(NULL) <= chrono_begin)
    {
        if(read_UDP(uc_sock, &receive_sin, buffer)<0) continue;
        write_UDP(uc_sock, &server_sin, buffer);
    }

    close(uc_sock);
    return 0;
}

你知道为什么会这样吗? 谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

问题是由使用相同MAC地址的Zedboards引起的。然后,交换机仅发送到连接到MAC地址的最后一个IP地址。

再见