⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sendfile.c

📁 开源的组播程序
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <time.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <time.h>#include <string.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <arpa/inet.h>#include <sys/time.h>#include <time.h>#include <libgen.h>#ifdef DMALLOC#include "dmalloc.h"#endif#include <rs.h>#include "pmtp.h"uint32_t process_upload (struct pmtp_upload *upload);int get_uploadsocket (struct pmtp_upload *upload); uint8_t send_upload_announcement (struct pmtp_upload *upload);uint8_t create_pmsp_header (struct pmtp_upload *upload, unsigned char *header);int main(int argc, char *argv[]) {	uint32_t bytes_read, segmentsize = (NN - NROOTS) * PMTP_PAYLOAD;	struct pmtp_upload upload;	struct pmtp_segment segment;	unsigned char sha_printable[60];	struct in_addr in_addr;	struct timespec sleeper; 	if (argc != 2) {		fprintf (stderr, "Usage: %s <filename>\n", argv[0]);		exit (1);	}	if (strlen (argv[1]) > 127) {		fprintf (stderr, "%s: Filename too long.\n", argv[0]);	 	exit (1);	}	upload.previous_invocation.tv_sec = 0;	upload.previous_invocation.tv_usec = 0;	upload.bytes_sent = 0;	upload.packets_sent = 0;	upload.bytes_sent_interval = 0;	upload.session.version = 1;	upload.session.codingid = 1;	upload.session.sessionid = 1;	upload.session.payload = PMTP_PAYLOAD;	upload.session.start = 5;	upload.session.family = AF_INET;	upload.session.protocol = SOCK_DGRAM;	inet_aton (PMTP_GROUP, &in_addr);	upload.session.group = in_addr.s_addr;	upload.session.port = htons (PMTP_PORT);	strncpy (upload.session.filename, argv[1], 127);	upload.session.filename[127] = 0;	upload.session.filesize = get_filesize (upload.session.filename);	upload.session.partoffset = 0;	upload.session.partlength = upload.session.filesize;	upload.session.bitrate = PMTP_BITRATE / 8000;	upload.credits = 0;	get_tigertree (upload.session.file_tigertree, upload.session.filename,		0, upload.session.filesize);	get_tigertree (upload.session.part_tigertree, upload.session.filename,		upload.session.partoffset, upload.session.partlength);	if (get_uploadsocket(&upload) == -1) {		fprintf (stderr, "Couldn't open upload socket.\n");		exit (1);	}	srandom(time(NULL));	if (DEBUG & DEBUG_CODING)		fprintf (stderr, "Code (%d / %d)\n", NN, NROOTS);	sleeper.tv_sec = 1;	sleeper.tv_nsec = 0;	while (upload.session.start > 0) {		send_upload_announcement (&upload); 		upload.session.start--;		nanosleep(&sleeper,NULL);	}	if ((upload.fd = open(upload.session.filename, O_RDONLY)) < 0) {		fprintf (stderr, "Error opening %s for reading\n",			upload.session.filename);		exit (1);	}	init_segment (&segment, NULL);	segment.segmentid = 0;	if((segment.codec=init_rs_char(SYMSIZE,GENPOLY,FCS,PRIM,NROOTS)) == NULL) {		fprintf(stderr, "init_rs_int failed!\n");		exit (1);	}	init_packet_buffer (&(upload.buffer));	if ((segment.packets = (uint8_t *) malloc (PMTP_PAYLOAD*NN)) == NULL) {		fprintf (stderr, "Couldn't malloc %d bytes for segment\n",			PMTP_PAYLOAD * NN);		exit (1);	}	sleeper.tv_sec = 0;	sleeper.tv_nsec = 100000000;	while ((bytes_read = read(upload.fd, segment.packets, segmentsize)) != 0) {		while (buffer_packets_free(&(upload.buffer)) < NN) {			process_upload (&upload);		nanosleep(&sleeper,NULL);		}		if (bytes_read == segmentsize) {			segment.payload_size = upload.session.payload;		} else {			segment.payload_size = (uint16_t) (bytes_read/(NN-NROOTS))+1;		}		if (DEBUG & DEBUG_SEGMENTS) 			fprintf (stderr, "Segment: %d, Payload %d, bytes %d\n",				segment.segmentid, segment.payload_size, bytes_read);		if (encode_segment (&segment, NROOTS) == NULL) {			fprintf (stderr, "Error encoding segment\n");			exit (1);		}		if (DEBUG & DEBUG_SEGMENTS_SHA)			fprintf (stderr, "Segment %d, Packets %d, Payload %d, SHA 0x%s\n",				segment.segmentid, segment.packets_received,				segment.payload_size, get_printable_sha (sha_printable,					segment.packets, NN * segment.payload_size));		if (buffer_segment (&upload, &segment) == 0) {			fprintf (stderr, "Error buffering segment %d.\n",segment.segmentid);			exit (1);		}		segment.segmentid++;	}	while (upload.buffer.size != 0) {		process_upload (&upload);		nanosleep(&sleeper,NULL);	}	printf ("Packets sent: %u, Bytes sent: %u.\n", upload.packets_sent,		upload.bytes_sent);	free_packet_buffer (&(upload.buffer));	free_segment (&segment);	close (upload.fd);	return 0;}uint8_t send_upload_announcement (struct pmtp_upload *upload) {	uint8_t headerlength;	uint8_t header[212];	memset (header, 0, 212);	headerlength = create_pmsp_header (upload, header);	if (DEBUG & DEBUG_PMSP) 		fprintf (stderr, "Sending PMSP packet with length %u: %s\n",			headerlength, &header[PMSP_HEADER_FILENAME]);	if (sendto (upload->s, header, headerlength, 0, (struct sockaddr *)			&(upload->s_in), sizeof (struct sockaddr_in)) < 0) {		perror ("sendto");		exit (1);	}	return headerlength;}uint8_t create_pmsp_header (struct pmtp_upload *upload, uint8_t *header) {	unsigned char *base;	unsigned char filename[128];	if (header == NULL) {		fprintf (stderr, "Header is a NULL pointer.\n");		exit (1);	}	encode_header_16 (header,		upload->session.version << 12 | upload->session.codingid );	encode_header_16 (header+PMSP_HEADER_SESSIONID, upload->session.sessionid);	encode_header_16 (header+PMSP_HEADER_PAYLOAD, upload->session.payload);	encode_header_16 (header+PMSP_HEADER_START, upload->session.start << 4);	/*	 * Source, multicast group and port are already in network byte order	 */	*((uint32_t *) (header + PMSP_HEADER_SOURCE)) = upload->session.source;	*((uint32_t *) (header + PMSP_HEADER_GROUP)) = upload->session.group;	*((uint16_t *) (header + PMSP_HEADER_PORT)) = upload->session.port;	memcpy (header + PMSP_HEADER_FILETIGERTREE, upload->session.file_tigertree,		24);	encode_header_16 (header+PMSP_HEADER_BITRATE, upload->session.bitrate);	encode_header_32 (header+PMSP_HEADER_FILESIZE+4, upload->session.filesize);	encode_header_32 (header+PMSP_HEADER_PARTOFFSET,upload->session.partoffset);	encode_header_32 (header+PMSP_HEADER_PARTLENGTH,upload->session.partlength);	memcpy (header + PMSP_HEADER_PARTTIGERTREE, upload->session.part_tigertree,		24);	strncpy (filename, upload->session.filename, 128);	filename[127] = 0;	base = basename (filename);	strncpy (header+PMSP_HEADER_FILENAME, base, 128);	return PMSP_HEADER_FILENAME + strlen(base);}uint32_t process_upload (struct pmtp_upload *upload) {	uint32_t bytes_budget, bytes_transmitted;	uint32_t packets_transmitted;	/* 	 * bitrate is in multiples of 8 Kbit/s. So to get to bytes per milisecond	 * we calculate bitrate * (1024 * 8)  bit/s / 8 bytes / 1000 miliseconds	*/	float byterate = 1.024 * upload->session.bitrate;	struct timeval now;	float delta; /* Time delta in miliseconds */	if (gettimeofday (&now, NULL) == -1) {		perror ("gettimeofday");		exit (1);	}	bytes_budget = (uint32_t) (byterate * 100.0);	if (upload->previous_invocation.tv_sec != 0) {		delta = (now.tv_sec - upload->previous_invocation.tv_sec) * 1000			+ (now.tv_usec - upload->previous_invocation.tv_usec) / 1000;		if (delta > SMOOTHING_SECONDS * 1000) {			fprintf (stderr, "Time delta %d > %d miliseconds.\n",				(uint32_t) delta, (uint32_t) SMOOTHING_SECONDS * 1000);			delta = SMOOTHING_SECONDS * 1000;		}		upload->credits += (uint32_t) (delta * byterate);		if (upload->bytes_sent_interval > upload->credits) {			upload->bytes_sent_interval -= upload->credits;		} else {			upload->bytes_sent_interval = 0;		}		bytes_budget = upload->credits < upload->bytes_sent_interval ?			0 : upload->credits - upload->bytes_sent_interval;		if (DEBUG & DEBUG_UPLOAD_PROCESSING) 			fprintf (stderr, "Now: %u.%u, Delta: %ums, byterate: %dKbit/s, credits: %u, Bytes: %u, ",				(uint32_t) now.tv_sec, (uint32_t) now.tv_usec / 1000,				(uint32_t) delta, (uint32_t) (byterate * 1000.0 / 1024.0),				(unsigned int) upload->credits, upload->bytes_sent_interval);	}	if (DEBUG & DEBUG_UPLOAD_PROCESSING) 		fprintf (stderr, "Sending budget %d bytes.\n", bytes_budget);	bytes_transmitted = send_buffer (upload->s, &(upload->s_in),		&(upload->buffer), bytes_budget, &packets_transmitted, 		&bytes_transmitted);	upload->credits -= bytes_transmitted;	upload->bytes_sent_interval += bytes_transmitted;	upload->bytes_sent += bytes_transmitted;	upload->previous_invocation = now;	return bytes_transmitted;}int get_uploadsocket (struct pmtp_upload *upload) {	char hostname[256];	struct hostent *hp;	int multicast_loop = 1;	if (gethostname (hostname, 255) == -1) {		perror ("gethostname");		exit (1);	}	if ((hp = gethostbyname2(hostname, AF_INET)) == NULL) {		fprintf (stderr, "%s: host unknown.\n", hostname);		exit (1);	}	if (hp->h_addr_list[0] == NULL) {		fprintf (stderr, "No network interfaces found.\n");		exit (1);	}	memcpy (&upload->session.source, hp->h_addr_list[0], 4);	if ((upload->s = socket (upload->session.family,			upload->session.protocol, 0)) < 0) {		perror ("socket");		exit (1);	}	if (setsockopt (upload->s, SOL_IP, IP_MULTICAST_LOOP, &multicast_loop,			sizeof(multicast_loop))) {		perror ("setsockopt");		exit (1);	}	upload->s_in.sin_family = upload->session.family;	upload->s_in.sin_addr.s_addr = upload->session.group;	upload->s_in.sin_port = upload->session.port;	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -