terça-feira, 4 de outubro de 2011

UDP Socket

Eu me bati um pouco para entender o processo e não encontrei nenhum exemplo de envio de streams por UDP. O código ainda não está pronto mas heis um cliente / servidor UDP com multithread e que envia uma estrutura de dados pela rede:

Cliente:





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

typedef struct t_medusa_pkt {
    short int pkt_size;
    char data[];
} medusa_pkt;

int main(int argc, char**argv) {
    int sockfd, n;
    struct sockaddr_in servaddr, cliaddr;

    if (argc != 2) {
        printf("usage:  udpcli \n");
        exit(1);
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    bzero(&servaddr, sizeof (servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);
    servaddr.sin_port = htons(32000);
    sendto(sockfd, "IM HERE", 7, 0, (struct sockaddr *) &servaddr,
           sizeof (servaddr));
    printf("HERE WE GO!\n");
    while (1) {
        medusa_pkt pkt;
        n = recvfrom(sockfd, &pkt, 100, 0, NULL, NULL);
        pkt.data[n - sizeof (short int) ] = 0;
        printf("RECEIVED %d BYTES ", n);
        printf("pkt_size: %d ", pkt.pkt_size);
        printf("data: %s \n", pkt.data);
    }
}



Servidor:

 

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


typedef struct t_medusa_pkt { // Struct do send
    short int pkt_size;
    char data[];
} medusa_pkt;

typedef struct t_udp_thread_data { //Data to thread
    int sockfd;
    struct sockaddr_in cliaddr;
} udp_thread_data;

pthread_t udp_wait_for_receive; // The thread id

void * send_data(void * args) {
    udp_thread_data *my_data;
    my_data = (udp_thread_data *) args;
    int sockfd = my_data->sockfd;
    struct sockaddr_in cliaddr = my_data->cliaddr;

    int i, n;
    char mesg[100];
    for (;;) {
        sprintf(mesg, "%d", i);
        medusa_pkt pkt; // struct to send heterogeneous data
        memcpy(pkt.data, mesg, strlen(mesg)); //
        pkt.data[strlen(mesg)] = 0;
        pkt.pkt_size = sizeof (short int) +strlen(mesg);
        n = sendto(sockfd, &pkt, pkt.pkt_size, 0,
                 (struct sockaddr *) &cliaddr, sizeof (cliaddr));
        printf("SENT %d BYTES pkt_size: %d  data: %s\n", n,
                 pkt.pkt_size, pkt.data);
        usleep(1000);
        i += 1000;
    }
}

int main(int argc, char**argv) {
    int sockfd, n;
    struct sockaddr_in servaddr, cliaddr;
    socklen_t len;
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    bzero(& servaddr, sizeof (servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(32000);
    bind(sockfd, (struct sockaddr *) &servaddr, sizeof (servaddr));
    len = sizeof (cliaddr);
    char * mesg = malloc(100);
    while (1) {
        n = recvfrom(sockfd, mesg, 7, 0, (struct sockaddr *) &cliaddr, &len);
        printf("Cliente conectado\n");
        udp_thread_data thread_data;
        thread_data.sockfd = sockfd;
        thread_data.cliaddr = cliaddr;
        pthread_create(&udp_wait_for_receive, NULL, 
                send_data, (void *) &thread_data);
    }
}


Umas referências ou exemplos que usei:
  • http://www.tenouk.com/Module40c.html
  • http://www.cs.ucsb.edu/~almeroth/classes/W01.176B/hw2/examples/

Nenhum comentário: