LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-05-2012, 06:00 AM   #1
sindhu4sind
Member
 
Registered: Apr 2012
Posts: 38

Rep: Reputation: Disabled
Smile UDP packet sending and receiving - how to calculate time consumed?


I have a implemented a udp packet sender and receiver. I want to calculate time for transaction, from sender to receiver how much time its taking..

Sender Code:
Code:
void senderFunc() {
/*some other code */
if((s1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    error_handler("\nERROR: in Socket\n");
    memset((char *) &me, 0, sizeof(me));
    me.sin_family = AF_INET;
    me.sin_port = PORT;
    if (inet_aton(G_IP, &me.sin_addr)==0)
    {
        fprintf(stderr, "inet_aton() failed\n");
        exit(1);
    }
    printf("\Tick - %d : %s",cntr++,str);
    sprintf(b1, "%s",str);  // Some Information in b1 buffer to transfer 
    if(sendto(s1, b1, sizeof(b1),0,(struct sockaddr *) &me,n)==-1)
    error_handler("\nERROR: in sendto()\n");
    close (s1);
    return;
    }
}
Receiver Code:
Code:
int receiverFunc () {
	struct sockaddr_in other, me;
	int s2, n, i = 1;
	char b2[BUFLEN];//, b2[BUFLEN];
	s2 = socket(AF_INET, SOCK_DGRAM,0);
	me.sin_family = AF_INET;
	me.sin_port = PORT;
	me.sin_addr.s_addr = htonl(INADDR_ANY);
	bind(s2,(struct sockaddr *)&me, sizeof(me));
	n=sizeof(other);
	int incr = 0;
	while (i){
		recvfrom (s2,b2,BUFLEN,0,(struct sockaddr *) &other, &n);
		printf ("\nSubnet 2: Tick - %d : %s",incr++, b2);
	}
	return 0;
}
How to calculate time if i send a packet from sender to receiver?

thanks for nice response always.. looking for your response..

Sindhu.
 
Old 06-05-2012, 06:48 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
To calculate a time delta, you need to have a reference point in time, say T1, and another time, say T2. The delta would be T2 - T1.

If you are sending a packet to another process on your the system, then you should be able to send the current time (T1), say using a resolution in microseconds, and then upon receipt of the packet, again capture the current system time (T2) so that you can perform the calculation.

If you are sending the packet to another machine, you can still employ the same process described above, however you need to ensure that both systems have their system times in sync.

An alternative, which is employed by such tools as "ping", is to send a packet with the current time and have the receiver reply back with the same message. When the sender process receives the reply, a computation can be performed as to how long the message took to make a round-trip.
 
Old 06-05-2012, 09:06 AM   #3
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by dwhitney67 View Post
If you are sending the packet to another machine, you can still employ the same process described above, however you need to ensure that both systems have their system times in sync.
Unless your machines have an accurate external clock source (atomic clock, high-frequency radio clock), one-way timing is very hard to do reliably. NTP is definitely not accurate enough for that.

Quote:
Originally Posted by dwhitney67 View Post
An alternative, which is employed by such tools as "ping", is to send a packet with the current time and have the receiver reply back with the same message.
Yes, this technique is recommended. Note that it is not necessary to have the actual timestamp in the message. It makes things simpler, but all you really need is to record the time when the original packet was sent, and when the response is received, then compare the two timestamps to get the round-trip time (RTT). To the other end, the timestamp (or identifier) is just opaque payload; it does not inspect it or use it in any way.

If both endpoints are bound (to a port), and there is only the single packet in flight at any time in either direction, then you don't need to have any kind of identifier in the UDP packet; each endpoint only needs to remember the accurate wall clock when they sent the packet, and when they received the response. It is just more robust to put the timestamp as the UDP packet payload.

My point is, it is quite difficult to find out the one-way trip duration. In fact, the round-trip time, RTT, is much more commonly used in the network environment. For most purposes one can assume that each leg takes about the same time. When there is heavy contention, or asymmetric connections (like ADSL lines, which tend to have much more bandwidth downstream than upstream), that is obviously not true; one leg tends to be faster, and one slower. Without some kind of a shared external clock, it is very difficult to find out how the RTT is divided between the two legs.
 
Old 06-05-2012, 09:20 AM   #4
sindhu4sind
Member
 
Registered: Apr 2012
Posts: 38

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by dwhitney67 View Post
An alternative, which is employed by such tools as "ping", is to send a packet with the current time and have the receiver reply back with the same message. When the sender process receives the reply, a computation can be performed as to how long the message took to make a round-trip.
This seems easy solution.. But i don't want to calculate rtt. I am just looking for time consumed from sending to receiving.

Quote:
Tcon = Tr - Ts
as you mentioned about time delta..

how can i send time along with ping packet? and it will be same time as sending time using udp?

Suppose I have a buffer value 100
unsigned char buffer[100];

then how this length of payload can be calculated using ping?

Quote:
ping -c 10 -s 1024 -q 192.168.2.1
Like this is mentioned that 10 Packets with payload 1024 transmitted to ip 192.168.2.1

is this correct?
Code:
ping -c 10 -s 100 -q 192.168.2.1
....
....
10 packets transmitted, 10 received, 0% packet loss, time 8999ms
> Single Packet Time = 8999/10
> Time in seconds 0.899

is this approach right to calculate time? please make me correct if i am on mistake...

Thank you so much for reply
 
Old 06-05-2012, 09:45 AM   #5
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
The ping utility will not be able to perform custom tasks (such as one-way time computations) for you. You could develop your own ping application, which transports the current time as part of the payload. You would need to create a socket using a type of SOCK_RAW and a protocol of IPPROTO_ICMP. Creating the packet and a customized payload is not a trivial matter; you would have to set the fields within the IP header and ICMP header, and then insert the payload itself before finally computing the checksum that is included in the header.

Here's an application (note it is written using C++) that I developed a while back; it mimics the basics of the ping utility as far as computing round-trip time measurements.
Code:
/*
# Copyright (C) 2003-2011 David M. Whitney (aka "dwhitney67")
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <TCPClientSocket.h>
#include <SocketUtility.h>

#include <sys/time.h>

#include <string>
#include <iostream>
#include <iomanip>
#include <unistd.h>
#include <csignal>
#include <cstring>
#include <cassert>


bool done = false;

double ComputeMsDelay(const timeval& tbegin, const timeval& tend);
void   sigHandler(int signo);


int main(int argc, char** argv)
{
  const std::string remoteAddr = (argc > 1 ? argv[1] : "127.0.0.1");

  signal(SIGINT, sigHandler);

  try
  {
    // Create the raw socket (root-permissions required!)
    socketpp::TCPClientSocket sock(AF_INET, SOCK_RAW, IPPROTO_ICMP);

    setuid(getuid());

    // Build the IP and ICMP headers
    static const size_t IP_LEN = sizeof(ip) + sizeof(icmphdr) + sizeof(timeval);

    unsigned char datagram[IP_LEN] = {0};
    ip*           iph    = reinterpret_cast<ip*>(datagram);
    icmphdr*      icmph  = reinterpret_cast<icmphdr*>(datagram + sizeof(ip));
    timeval*      tbegin = reinterpret_cast<timeval*>(datagram + sizeof(ip) + sizeof(icmphdr));

    iph->ip_hl  = sizeof(ip) >> 2;
    iph->ip_v   = 4;
    iph->ip_tos = IPTOS_PREC_ROUTINE;
    iph->ip_len = htons(IP_LEN);
    iph->ip_id  = htons(54321);
    iph->ip_off = 0;
    iph->ip_ttl = IPDEFTTL;
    iph->ip_p   = IPPROTO_ICMP;

    in_addr_t src = inet_addr("10.0.0.2");
    in_addr_t dst = inet_addr(remoteAddr.c_str());

    memcpy(&iph->ip_src, &src, sizeof(iph->ip_src));
    memcpy(&iph->ip_dst, &dst, sizeof(iph->ip_dst));

    iph->ip_sum = socketpp::headerChecksum(reinterpret_cast<const uint16_t*>(iph), iph->ip_hl << 2);

    double totalDelay = 0;
    int    seq        = 1;

    // Send ICMP datagram
    sockaddr_in dst_sin;
    sock.fillAddress(reinterpret_cast<sockaddr*>(&dst_sin), sizeof(dst_sin), 0, remoteAddr.c_str());

    for (int id = 1; !done; ++id, ++seq)
    {
      memset((char*) icmph, 0, sizeof(icmphdr));
      gettimeofday(tbegin, 0);

      icmph->type             = ICMP_ECHO;
      icmph->code             = 0;
      icmph->un.echo.id       = htons(id);
      icmph->un.echo.sequence = htons(seq);
      icmph->checksum         = socketpp::headerChecksum(reinterpret_cast<const uint16_t*>(icmph),
                                                         sizeof(icmphdr) + sizeof(timeval));

      sock.send(std::basic_string<unsigned char>(datagram, datagram + IP_LEN), dst_sin);

      // Check if a reply is forthcoming...
      timeval timeout = {5, 0};

      if (sock.activityDetected(&timeout))
      {
        // Receive reply
        std::basic_string<unsigned char> response;
        sock >> response;

        // get the time value from the response packet
        const timeval* begin = reinterpret_cast<const timeval*>(response.data() + (IP_LEN - sizeof(timeval)));

        // Compute and display time delay
        timeval end;
        gettimeofday(&end, 0);

        const double delay = ComputeMsDelay(*begin, end);
        totalDelay += delay;

        std::cout << "time: " << delay << " ms" << std::endl;

        usleep(500000);   // delay half second before sending next ICMP packet
      }
      else
      {
        std::cout << "no response from remote host." << std::endl;
        done = true;
      }
    }

    std::cout << "\navg time: " << totalDelay / seq << " ms" << std::endl;
  }
  catch (socketpp::SocketException& e)
  {
    std::cerr << e.what() << std::endl;
    return 1;
  }
}


double ComputeMsDelay(const timeval& tbegin, const timeval& tend)
{
  time_t      secs  = tend.tv_sec  - tbegin.tv_sec;
  suseconds_t usecs = tend.tv_usec - tbegin.tv_usec;

  if (usecs < 0)
  {
    --secs;
    usecs += 1000000;
  }

  return ((double) secs + (double) usecs / 1000000) * 1000;
}


void sigHandler(int signo)
{
  done = true;
}

Last edited by dwhitney67; 06-05-2012 at 09:48 AM.
 
1 members found this post helpful.
  


Reply

Tags
performance, time, udp



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Sending and Receiving IP Packet sindhu4sind Linux - Kernel 2 04-21-2012 04:29 AM
[SOLVED] Sending/receiving UDP packets through a PF_PACKET socket mibo Programming 21 12-06-2011 03:14 AM
Calculate total memory consumed by user emymcse Linux - General 12 09-23-2010 05:26 AM
How to specify source port when sending UDP packet socialjazz Programming 4 09-19-2006 08:15 PM
raw packet sending & receiving sjcoder Programming 7 01-11-2006 04:07 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:04 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration