int mcast_send_frame( mcast_sender *v, const VJFrame *frame, uint8_t *buf, int total_len, long ms,int port_num, int mode) { int i; packet_header_t header = packet_construct_header( 1 ); frame_info_t info; info.fmt = frame->format; info.width = frame->width; info.height = frame->height; info.len = total_len; info.mode = mode; uint32_t frame_num = stamp_make(v); header.timeout = ms * 1000; header.usec = frame_num; uint8_t chunk[PACKET_PAYLOAD_SIZE]; int res = 0; veejay_memset( chunk, 0,sizeof(chunk)); //@ If we can send in a single packet: if( total_len <= CHUNK_SIZE ) { header.seq_num = 0; header.flag = 1; header.length = 1; packet_put_padded_data( &header,&info, chunk, buf, total_len); res = mcast_send( v, chunk, PACKET_PAYLOAD_SIZE, port_num ); if(res <= 0 ) return -1; return 1; } int pred_chunks = (total_len / CHUNK_SIZE); int bytes_left = (total_len % CHUNK_SIZE); header.length = pred_chunks + ( bytes_left > 0 ? 1 : 0 ); for( i = 0; i < pred_chunks; i ++ ) { const uint8_t *data = buf + (i * CHUNK_SIZE); header.seq_num = i; header.flag = 1; packet_put_data( &header, &info, chunk, data ); res = mcast_send( v, chunk, PACKET_PAYLOAD_SIZE, port_num ); if(res <= 0 ) { return -1; } } if( bytes_left ) { i = header.length-1; header.seq_num = i; header.flag = 1; int bytes_done = packet_put_padded_data( &header, &info, chunk, buf + (i * CHUNK_SIZE), bytes_left ); veejay_memset( chunk + bytes_done, 0, (PACKET_PAYLOAD_SIZE-bytes_done)); res = mcast_send( v, chunk, PACKET_PAYLOAD_SIZE, port_num ); if( res <= 0 ) { veejay_msg(0, "Unable to send last packet"); return -1; } } if( frame_num == 0xffff ) stamp_reset(v); return 1; }
int main(int argc, char **argv) { char host_name[MAXHOSTNAMELEN+1]; char host_addr[MAXHOSTNAMELEN+1]; char master_host_name[MAXHOSTNAMELEN+1]; char group_address[MAXHOSTNAMELEN+1]; short port; int num_bursts; int num_messages_per_burst; int node_id; int argNb=1; strcpy(host_name, argv[argNb++]); strcpy(host_addr, argv[argNb++]); node_id = atoi(argv[argNb++]); strcpy(master_host_name, argv[argNb++]); strcpy(group_address, argv[argNb++]); port = atoi(argv[argNb++]); num_bursts = atoi(argv[argNb++]); num_messages_per_burst = atoi(argv[argNb++]); request_size = atoi(argv[argNb++]); double rate = atof(argv[argNb++]); // rate represents desired rate in req/s const double delay = 1/rate; const long delay_ns = (long)(delay*1e9); fprintf(stderr, "******************************\n* multicast test\n****************************************\n"); fprintf(stderr, "Data is:\n* hostname = %s\n* node_id = %d\n* master_host_name = %s\n* group address = %s\n* port = %d\n* num_bursts = %d\n* msgs per burst = %d\n* request size = %d\n* rate = %g\n", host_name, node_id, master_host_name, group_address, port, num_bursts, num_messages_per_burst, request_size, rate); char hname[MAXHOSTNAMELEN]; gethostname(hname, MAXHOSTNAMELEN); struct sockaddr_in gaddr; bzero(&gaddr, sizeof(gaddr)); gaddr.sin_family = AF_INET; gaddr.sin_addr.s_addr = inet_addr(group_address); gaddr.sin_port = htons(port); sa_group_address = (struct sockaddr*)&gaddr; // Initialize socket. sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); int flag_on = 1; /* set reuse port to on to allow multiple binds per host */ if ((setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag_on, sizeof(flag_on))) < 0) { perror("setsockopt() failed"); exit(1); } struct in_addr laddr; laddr.s_addr = inet_addr(host_addr); if ((setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &laddr, sizeof(laddr))) < 0) { perror("setsockopt() failed for binding multicast to interface"); exit(1); } int error = bind(sock, (struct sockaddr*)&gaddr, sizeof(gaddr)); if (error < 0) { perror("Unable to name socket"); exit(1); } // explicitely enable loopback unsigned char loop = 1; if ((setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop))) < 0) { perror("setsockopt() failed for enabling loop"); exit(1); } // Set TTL larger than 1 to enable multicast across routers. unsigned char i = 20; if ((setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&i, sizeof(i))) < 0) { perror("unable to change TTL value"); exit(1); } struct ip_mreq multicast_req; multicast_req.imr_multiaddr.s_addr = inet_addr(group_address); multicast_req.imr_interface.s_addr = inet_addr(host_addr); if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &multicast_req, sizeof(multicast_req))) < 0) { perror("Unable to join group"); exit(1); } // Create socket to communicate with manager int manager; if ((manager = socket(AF_INET, SOCK_STREAM, 0)) == -1) { th_fail("Could not create socket"); } // Fill-in manager address Address desta; bzero((char *)&desta, sizeof(desta)); struct hostent *hent = gethostbyname(master_host_name); if (hent == 0) { th_fail("Could not get hostent"); } // desta.sin_addr.s_addr = inet_addr("192.168.20.6"); // sci6 desta.sin_addr.s_addr = ((struct in_addr*)hent->h_addr_list[0])->s_addr; desta.sin_family = AF_INET; desta.sin_port = htons(MANAGER_PORT); if (connect(manager, (struct sockaddr *) &desta, sizeof(desta)) == -1) { th_fail("Could not connect name to socket"); } thr_command out, in; pthread_t requests_from_others_thread; if (pthread_create(&requests_from_others_thread, 0, &requests_from_others, host_name) != 0) { fprintf(stderr, "Failed to create the thread for receiving messages from other replicas\n"); exit(1); } // Tell manager we are up if (send(manager, &out, sizeof(out), 0) < sizeof(out)) { fprintf(stderr, "Problem with send to manager\n"); exit(-1); } fprintf(stderr, "Starting the bursts (num_bursts = %d)\n", num_bursts); int req_cnt = 0; mcast_req *req = (mcast_req*)malloc(request_size); req->type = 0xdeadbeef; req->id = req_cnt; req->node_id = node_id; req->size = request_size; req->payload = req->size - sizeof(mcast_req); fprintf(stderr,"\n"); for (i = 0; i < num_bursts; i++) { char *data = (char*)∈ int ssize = sizeof(in); int ret = 0; while (ssize) { ret = recv(manager, data, ssize, MSG_WAITALL); if (ret == -1 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) { continue; } else if (ret < 0) { fprintf(stderr, "Error receiving msg from manager\n"); perror(NULL); exit(1); } ssize -= ret; data += ret; } fprintf(stderr, "Starting burst #%d\n", i); //char a=getchar(); // Loop invoking requests // int j=0; // while(true){ // j++ int s = 0; /*s = in.num_iter;*/ int j; struct timespec ts_obt; struct timespec ts_fire; struct timeval tv; gettimeofday(&tv, NULL); for (j = s; j < num_messages_per_burst; j++) { /*fprintf(stderr, "Send a new message\n");*/ int retval = 0; int len = 0; req->id = req_cnt++; if (j == s) { clock_gettime(CLOCK_REALTIME, &ts_obt); } retval = mcast_send(req, &len); if (retval == -1) { fprintf(stderr, "multicast_replica: problem invoking request\n"); } else { /*fprintf(stderr, "Sent one\n");*/ if (j%1000 == 0) fprintf(stderr, "."); } { struct timespec ts_remain; ts_fire.tv_sec = ts_obt.tv_sec; ts_fire.tv_nsec = ts_obt.tv_nsec + delay_ns; while (ts_fire.tv_nsec >= 1000000000) { ts_fire.tv_nsec -= 1000000000; ts_fire.tv_sec += 1; } if (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts_fire, &ts_remain) == -1 && errno == EINTR) { struct timespec ts_rem = ts_remain; while (clock_nanosleep(CLOCK_REALTIME, 0, &ts_remain, &ts_rem)==-1 && errno == EINTR) { ts_remain = ts_rem; } } ts_obt = ts_fire; } } fprintf(stderr,"\n"); struct timeval tv_end; gettimeofday(&tv_end, NULL); struct timeval timediff; timediff = tv_diff(tv_end, tv); fprintf(stderr, "[Node %s] Finished burst %d: total time %d s, %d us\n", host_name, i, timediff.tv_sec, timediff.tv_usec); // out.num_iter = num_messages_per_burst; if (send(manager, &out, sizeof(out), 0) <= 0) { fprintf(stderr, "Sendto failed"); exit(-1); } } free(req); error = setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &multicast_req, sizeof(multicast_req)); shutdown(manager, SHUT_RDWR); close(manager); sleep(4); do_run = 0; sleep(1); /*pthread_kill(requests_from_others_thread, SIGINT);*/ /*pthread_join(requests_from_others_thread, NULL);*/ fprintf(stderr, "[Node %s] received a total of %ld requests\n", host_name, received_total); fprintf(stderr, "Client exiting\n"); return 0; }