카테고리 없음

멀티캐스트 송수신 속도 재기

blade. 2011. 11. 4. 15:30
송수신 속도를 60 마이크로 초 이하로 줄일 수 있는 방법을 모르겠음.



송신 프로그램에서 수신 프로그램으로 멀티캐스트 전송.
걸리는 시간은 평균 60.605 * 10-6 초.
 
리눅스 커널 : 2.6.32
CPU : Intel(R) Xeon(R) CPU E5640  @ 2.67GHz x 16코어
NIC : 10G (같은 서버 안에서 처리되는거라서 NIC를 거치진않음)

===

#include <time.h>

#include <stdlib.h>

#include <stdio.h>


#include "Util.h"


#include <sys/types.h>  /* for type definitions */

#include <sys/socket.h> /* for socket API calls */

#include <netinet/in.h> /* for address structs */

#include <arpa/inet.h>  /* for sockaddr_in */ 

#include <stdio.h>      /* for printf() and fprintf() */

#include <stdlib.h>     /* for atoi() */

#include <string.h>     /* for strlen() */

#include <unistd.h>     /* for close() */


#define MAX_LEN  1024   /* maximum receive string size */

#define MIN_PORT 1024   /* minimum port allowed */

#define MAX_PORT 65535  /* maximum port allowed */


long g_total_recv_count = 0;

double g_total_diff = 0;

struct timespec tp;


int 

main(int argc, char *argv[])

{

int sock;                     /* socket descriptor */

int flag_on = 1;              /* socket option flag */

struct sockaddr_in mc_addr;   /* socket address structure */

char recv_str[MAX_LEN+1];     /* buffer to receive string */

int recv_len;                 /* length of string received */

struct ip_mreq mc_req;        /* multicast request structure */

char* mc_addr_str;            /* multicast IP address */

//  unsigned short mc_port;       /* multicast port */

int mc_port;       /* multicast port */

struct sockaddr_in from_addr; /* packet source */

unsigned int from_len;        /* source addr length */


/* validate number of arguments */

if (argc != 3)

{

fprintf(stderr, 

"Usage: %s <Multicast IP> <Multicast Port>\n", 

argv[0]);

exit(1);

}


mc_addr_str = argv[1];      /* arg 1: multicast ip address */

mc_port = atoi(argv[2]);    /* arg 2: multicast port number */


/* validate the port range */

if ((mc_port < MIN_PORT) || (mc_port > MAX_PORT))

{

fprintf(stderr, "Invalid port number argument %d.\n",

mc_port);

fprintf(stderr, "Valid range is between %d and %d.\n",

MIN_PORT, MAX_PORT);

exit(1);

}


/* create socket to join multicast group on */

if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)

{

perror("socket() failed");

exit(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);

}

/* construct a multicast address structure */

memset(&mc_addr, 0, sizeof(mc_addr));

mc_addr.sin_family      = AF_INET;

mc_addr.sin_addr.s_addr = htonl(INADDR_ANY);

mc_addr.sin_port        = htons(mc_port);


/* bind to multicast address to socket */

if ((bind(sock, (struct sockaddr *) &mc_addr, 

sizeof(mc_addr))) < 0)

{

perror("bind() failed");

exit(1);

}

/* construct an IGMP join request structure */

mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str);

mc_req.imr_interface.s_addr = htonl(INADDR_ANY);

/* send an ADD MEMBERSHIP message via setsockopt */

if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, 

(void*) &mc_req, sizeof(mc_req))) < 0)

{

perror("setsockopt() failed");

exit(1);

}


for (;;)

{

memset(recv_str, 0, sizeof(recv_str));

from_len = sizeof(from_addr);

memset(&from_addr, 0, from_len);

if ((recv_len = recvfrom(sock, recv_str, MAX_LEN, 0, 

(struct sockaddr*)&from_addr, &from_len)) < 0)

{

perror("recvfrom() failed");

exit(1);

}

////////////

clock_gettime( CLOCK_REALTIME, &tp );

recv_str [recv_len] = 0;

long u1 = atol( &recv_str[11] );

recv_str[10] = 0x00;

long h1 = atol( &recv_str[0] );

long diff = tp.tv_nsec - u1;

// printf( "%10ld.%09ld <- %10ld.%09ld. diff(%ld)\n", tp.tv_sec, tp.tv_nsec, h1, u1, diff );

if( diff < 1000*1000 && diff > 0 )

{

g_total_recv_count++;

g_total_diff += diff;

}


if( g_total_recv_count >= 10 )

{

printf( "%06ld.%06ld : %03.3f micro sec (per %ld packets) Received %d bytes from %s\n",

lGetHHMMSS(), lGetUSEC(),

g_total_recv_count,

g_total_diff/g_total_recv_count/1000,

recv_len, inet_ntoa(from_addr.sin_addr) );

g_total_recv_count = 0;

g_total_diff = 0;


sleep( 1 );

}

}

/* send a DROP MEMBERSHIP message via setsockopt */

if ((setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, 

(void*) &mc_req, sizeof(mc_req))) < 0)

{

perror("setsockopt() failed");

exit(1);

}

close(sock);  

}


// endoffile : mcreceive.cpp

 

===

#include <time.h>
#include <sys/time.h>
#include <sys/types.h>   /* for type definitions */
#include <sys/socket.h>  /* for socket API function calls */
#include <netinet/in.h>  /* for address structs */
#include <arpa/inet.h>   /* for sockaddr_in */
#include <stdio.h>       /* for printf() */
#include <stdlib.h>      /* for atoi() */
#include <string.h>      /* for strlen() */
#include <unistd.h>      /* for close() */
#include "Util.h"

#define MAX_LEN  1024    /* maximum string size to send */
#define MIN_PORT 1024    /* minimum port allowed */
#define MAX_PORT 65535   /* maximum port allowed */

struct timespec tp;

int 
main(int argc, char *argv[])
{
int sock;                   /* socket descriptor */
char send_str[MAX_LEN];     /* string to send */
struct sockaddr_in mc_addr; /* socket address structure */
unsigned int send_len;      /* length of string to send */
char* mc_addr_str;          /* multicast IP address */
unsigned short mc_port;     /* multicast port */
unsigned char mc_ttl=1;     /* time to live (hop count) */
/* validate number of arguments */
if (argc != 4)
{
fprintf(stderr, 
"Usage: %s <Multicast IP> <Multicast Port> <TTL>\n", 
argv[0]);
exit(1);
}
mc_addr_str = argv[1];       /* arg 1: multicast IP address */
mc_port     = atoi(argv[2]); /* arg 2: multicast port number */
mc_ttl = 5;
// if( argv[3][0] != 0x00 ) mc_ttl      = atoi(argv[3]); /* arg 2: multicast port number */
/* validate the port range */
if ((mc_port < MIN_PORT) || (mc_port > MAX_PORT))
{
fprintf(stderr, "Invalid port number argument %d.\n", mc_port);
fprintf(stderr, "Valid range is between %d and %d.\n", MIN_PORT, MAX_PORT);
exit(1);
}
/* create a socket for sending to the multicast address */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
perror("socket() failed");
exit(1);
}
/* set the TTL (time to live/hop count) for the send */
if ((setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (void*) &mc_ttl, sizeof(mc_ttl))) < 0)
{
perror("setsockopt() failed");
exit(1);
  
/* construct a multicast address structure */
memset(&mc_addr, 0, sizeof(mc_addr));
mc_addr.sin_family      = AF_INET;
mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str);
mc_addr.sin_port        = htons(mc_port);
printf("Begin typing (return to send, ctrl-C to quit):\n");
/* clear send buffer */
memset(send_str, 0, sizeof(send_str));

long cnt = 0;

long u1 = lGetUSEC();
long h1 = lGetHHMMSS();
while( 1 )
{
clock_gettime( CLOCK_REALTIME, &tp );
sprintf( send_str, "%10ld.%09ld", tp.tv_sec, tp.tv_nsec );
send_len = strlen(send_str);
/* send string to multicast address */
if ((sendto(sock, send_str, send_len, 0, (struct sockaddr *) &mc_addr,  sizeof(mc_addr))) != send_len)
{
perror("sendto() sent incorrect number of bytes");
exit(1);
}
if( cnt % 100 == 0 )
printf( "%06ld.%06ld : send_str %ld (%s)\n", 
lGetHHMMSS(), lGetUSEC(),
cnt, send_str 
);
usleep( 1000*10 );
cnt++;
}

long u2 = lGetUSEC();
long h2 = lGetHHMMSS();
if( u2 - u1 < 0 )
{
h2--;
u2 += 1000*1000*1000;
}

printf( "\n=== diff : %06ld.%09ld\n", h2 - h1, u2 - u1 );
close(sock);  
exit(0);
}

// endoffile : mcsend.cpp