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

📄 wrapper-new-ttcp.cpp

📁 最新的版本ACE-5.6.8,刚从外文网上搬下,与大家分享.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// $Id: wrapper-new-ttcp.cpp 80826 2008-03-04 14:51:23Z wotte $

/*
 *    T T C P . C
 *
 * Test TCP connection.  Makes a connection on port 5001
 * and transfers fabricated buffers or data copied from stdin.
 *
 * Usable on 4.2, 4.3, and 4.1a systems by defining one of
 * BSD42 BSD43 (BSD41a)
 * Machines using System V with BSD sockets should define SYSV.
 *
 * Modified for operation under 4.2BSD, 18 Dec 84
 *      T.C. Slattery, USNA
 * Minor improvements, Mike Muuss and Terry Slattery, 16-Oct-85.
 * Modified in 1989 at Silicon Graphics, Inc.
 *      catch SIGPIPE to be able to print stats when receiver has died
 *      for tcp, don't look for sentinel during reads to allow small transfers
 *      increased default buffer size to 8K, nbuf to 2K to transfer 16MB
 *      moved default port to 5001, beyond IPPORT_USERRESERVED
 *      make sinkmode default because it is more popular,
 *              -s now means don't sink/source
 *      count number of read/write system calls to see effects of
 *              blocking from full socket buffers
 *      for tcp, -D option turns off buffered writes (sets TCP_NODELAY sockopt)
 *      buffer alignment options, -A and -O
 *      print stats in a format that's a bit easier to use with grep & awk
 *      for SYSV, mimic BSD routines to use most of the existing timing code
 * Modified by Steve Miller of the University of Maryland, College Park
 *      -b sets the socket buffer size (SO_SNDBUF/SO_RCVBUF)
 * Modified Sept. 1989 at Silicon Graphics, Inc.
 *      restored -s sense at request of tcs@brl
 * Modified Oct. 1991 at Silicon Graphics, Inc.
 *      use getopt(3) for option processing, add -f and -T options.
 *      SGI IRIX 3.3 and 4.0 releases don't need #define SYSV.
 * Modified Aug.1993 at University Paderborn, Germany
 *  some SVR4 changes and time functions changed to itimer() calls
 * Modified by Douglas C. Schmidt September 28, 1994
 *  added support for testing UNIX domain socket performance
 * Modified by Tim Harrison May, 1995
 *  added support for ACE wrappers
 * Distribution Status -
 *      Public Domain.  Distribution Unlimited.
 */

/* #define BSD43 */
/* #define BSD42 */
/* #define BSD41a */
// #define SYSV /* required on SGI IRIX releases before 3.3 */

#include "ace/Log_Msg.h"
#include "ace/SOCK_Connector.h"
#include "ace/SOCK_Acceptor.h"

#include <stdio.h>
#include <signal.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <memory.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h> /* struct itimerval */
#include <limits.h>
#include <sys/un.h>
#include <unistd.h>

ACE_SOCK_Connector connector_factory;
ACE_SOCK_Acceptor acceptor_factory;
ACE_INET_Addr address;

#if defined(SYSV)
#define bcopy(b1,b2,n)  memcpy(b2,b1,n)
#define bzero(b1,n)             memset(b1,0,n)
#include <sys/times.h>
#include <sys/param.h>

struct rusage
  {
    struct timeval ru_utime, ru_stime;
  };
#define RUSAGE_SELF 0

#else
#include <sys/resource.h>
#endif

struct sockaddr_in sinme;
struct sockaddr_un sunme;
struct sockaddr_in sinhim;
struct sockaddr_un sunhim;
struct sockaddr_in frominet;
struct sockaddr_un fromunix;

struct Session_Control_Message
{
  long nbuf_;
  // number of buffers that will be sent this round.
  long size_;
  // size of the buffers that will be sent
} session_control_buf;

struct Data_Control_Message
{
  long size_;
  char data_;
} *message_buf;

int fromlen;
int domain = PF_INET;           /* Default is to use Internet domain sockets. */
char *domainname;               /* Rendezvous address for UNIX domain sockets. */
int fd;                         /* fd of network socket */

int data_buf_len = 1024 * 1024 * 2;  // length of data portion
long total_msg_len;                  // length of entire message
char *data_buf;                      // pointer to data portion
int nbuf = 2 * 1024;      /* number of buffers to send in sinkmode */

int bufoffset = 0;        /* align buffer to this */
int bufalign = 16 * 1024; /* modulo this */

int udp = 0;              /* 0 = tcp, !0 = udp */
int options = 0;          /* socket options */
int one = 1;              /* for 4.3 BSD style setsockopt() */
short port = 5001;        /* TCP port number */
char *host;               /* ptr to name of host */
int trans;                /* 0=receive, !0=transmit mode */
int sinkmode = 0;         /* 0=normal I/O, !0=sink/source mode */
int verbose = 0;          /* 0=print basic info, 1=print cpu rate, proc
                           * resource usage. */
int nodelay = 0;          /* set TCP_NODELAY socket option */
int b_flag = 0;           /* use mread() */
int sockbufsize = 0;      /* socket buffer size to use */
char fmt = 'K';           /* output format: k = kilobits, K = kilobytes,
                           * m = megabits, M = megabytes,
                           * g = gigabits, G = gigabytes */
int touchdata = 0;        /* access data after reading */

struct hostent *addr;
extern int errno;
extern int optind;
extern char *optarg;

char Usage[] = "\
Usage: ttcp -t [-options] host [ < in ]\n\
       ttcp -r [-options > out]\n\
Common options:\n\
        -l ##   length of bufs read from or written to network (default 8192)\n\
        -u      use UDP instead of TCP\n\
        -U      use UNIX domain sockets instead of Internet domain sockets\n\
        -p ##   port number to send to or listen at (default 5001)\n\
        -s      -t: source a pattern to network\n\
                -r: sink (discard) all data from network\n\
        -A      align the start of buffers to this modulus (default 16384)\n\
        -O      start buffers at this offset from the modulus (default 0)\n\
        -v      verbose: print more statistics\n\
        -d      set SO_DEBUG socket option\n\
        -b ##   set socket buffer size (if supported)\n\
        -f X    format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n\
Options specific to -t:\n\
        -n##    number of source bufs written to network (default 2048)\n\
        -D      don't buffer TCP writes (sets TCP_NODELAY socket option)\n\
Options specific to -r:\n\
        -B      for -s, only output full blocks as specified by -l (for TAR)\n\
        -T      \"touch\": access each byte as it's read\n\
";

char stats[128];
unsigned long nbytes;         /* bytes on net */
unsigned long numCalls = 0;   /* # of I/O system calls */
double cput, realt;           /* user, real time (seconds) */

void err (char *s);
void mes (char *s);
void pattern (register char *cp, register int cnt);
char *outfmt (double b);
void prep_timer (void);
double read_timer (char *str, int len);
static void prusage (register struct rusage *r0, struct rusage *r1, struct timeval *e, struct timeval *b, char *outp);
static void tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1);
static void tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0);
static void psecs (long l, register char *cp);
void delay (int us);
int mread (int fd, register char *bufp, unsigned n);
int Nread (ACE_SOCK_Stream &s, void *buf, int count);
int Nwrite (ACE_SOCK_Stream &s, void *buf, int count);

#if !defined (__cplusplus)
typedef void (*SIG_TYP)();
#else
typedef void (*SIG_TYP)(int);
#endif

#ifdef SVR4
void
sigpipe (int foo)
#else
void
sigpipe ()
#endif
{
}

void sigpipe(int foo)
{
   printf("Caught signal %d\n", foo);
}

char *title = 0;
int new_line = 0;

int
ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
  ACE_SOCK_Stream connection_stream;
  int c;

  printf("HZ = %d\n", HZ);
  if (argc < 2)
    goto usage;

  while ((c = getopt (argc, argv, "drstU:uvBDTb:f:l:n:p:A:O:L:xh:")) != -1)
    {
      switch (c)
        {
        case 'h':
          host = optarg;
          break;
        case 'x':
          new_line = 1;
          break;
        case 'L':
          title = optarg;
          break;
        case 'B':
          b_flag = 1;
          break;
        case 't':
          trans = 1;
          break;
        case 'r':
          trans = 0;
          break;
        case 'd':
          options |= SO_DEBUG;
          break;
        case 'D':
        #ifdef TCP_NODELAY
          nodelay = 1;
        #else
          fprintf (stderr,
                   "ttcp: -D option ignored: TCP_NODELAY socket option not supported\n");
        #endif
          break;
        case 'n':
          nbuf = atoi (optarg);
          break;
        case 'l':
          data_buf_len = atoi (optarg);
          break;
        case 's':
          sinkmode = !sinkmode;
          break;
        case 'p':
          port = atoi (optarg);
          break;
        case 'U':
          domain = PF_UNIX;
          domainname = optarg;
          break;
        case 'u':
          udp = 1;
          break;
        case 'v':
          verbose = 1;
          break;
        case 'A':
          bufalign = atoi (optarg);
          break;
        case 'O':
          bufoffset = atoi (optarg);
          break;
        case 'b':
        #if defined(SO_SNDBUF) || defined(SO_RCVBUF)
          sockbufsize = atoi (optarg);
        #else
          fprintf (stderr,
                   "ttcp: -b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported\n");
        #endif
          break;
        case 'f':
          fmt = *optarg;
          break;
        case 'T':
          touchdata = 1;
          break;

        default:
          goto usage;
      }
    }

  /* if transmitter, create remote address to transmit to.  */

  if (trans)
    {
      if (address.set (port, host) == -1)
        perror ("address.set"), exit (1);
    }

  /* else, receiver create address to listen on */
  else
    {
      address.set (port);
    }

  total_msg_len = sizeof (long) + data_buf_len;

  // allocate the buffer
  message_buf = (Data_Control_Message *) malloc (total_msg_len);
  if (message_buf == 0)
    err ("malloc");

//  if (bufalign != 0)
//    message_buf += (bufalign - ((int) message_buf % bufalign) + bufoffset) % bufalign;

  // let's go ahead and set the control message for every send right now
  message_buf->size_ = data_buf_len;

  session_control_buf.nbuf_ = nbuf;
  session_control_buf.size_ = data_buf_len;

  //
  // print out option values for trans and receiver
  //

  if (trans)
    {
      fprintf (stdout,
               "ttcp-t: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d",
               data_buf_len, nbuf, bufalign, bufoffset, port);
      if (sockbufsize)
        fprintf (stdout, ", sockbufsize=%d", sockbufsize);
      fprintf (stdout, "  %s  -> %s\n",
               domain == PF_INET ? (udp ? "udp" : "tcp") : "unix",
               host == 0 ? domainname : host);
    }
  else // receiver
    {
      fprintf (stdout,
               "ttcp-r: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d",
               data_buf_len, nbuf, bufalign, bufoffset, port);
      if (sockbufsize)
        fprintf (stdout, ", sockbufsize=%d", sockbufsize);
      fprintf (stdout, "  %s\n", domain == PF_INET ? (udp ? "udp" : "tcp") : "unix");
    }

  mes ("socket");

  //
  // connect and accept
  //

  if (!udp)
    {
      signal (SIGPIPE, (SIG_TYP) sigpipe);

      /* the transmitter will set options and connect to receiver */
      if (trans)
        {
          // turn off weird ack things
          if (nodelay)
            {
              struct protoent *p = getprotobyname ("tcp");

              if (p && connection_stream.set_option (p->p_proto,
                                                    TCP_NODELAY,
                                                    (char *)& one,
                                                    sizeof (one)))
                err ("setsockopt: nodelay");
              mes ("nodelay");
            }
          if (connector_factory.connect (connection_stream, address) == -1)
            perror ("connection failed"), exit (1);
          fprintf (stdout,
                  "ttcp-t: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d",
                  data_buf_len, nbuf, bufalign, bufoffset, port);

          if (sockbufsize)
            {
              if (connection_stream.set_option (SOL_SOCKET,
                                                SO_SNDBUF,
                                                (char *) &sockbufsize,
                                                sizeof sockbufsize) == -1)
                err ("acceptor_factory.set_option");
              mes ("sndbuf");
            }
        }

      /* receiver will listen for connections from the transmitter */
      else
        {
          if (acceptor_factory.open (address, 1) == -1)
            perror ("acceptor open"), exit (1);

          if (sockbufsize)
            {
              if (connection_stream.set_option (SOL_SOCKET,
                                                SO_RCVBUF,
                                                (char *) &sockbufsize,
                                                sizeof sockbufsize) == -1)
                err ("acceptor_factory.set_option");
              mes ("rcvbuf");
            }

          ACE_INET_Addr remote_address;

          if (acceptor_factory.accept (connection_stream,
                                      (ACE_Addr *) &remote_address) == -1)
            perror ("acceptor accept"), exit (1);

          // set the window size

          fprintf (stderr,
                  "ttcp-r: accept from %s\n",
                  remote_address.get_host_name());
        }
    }

  //
  // start timer
  //

  errno = 0;
  if (trans)
    {
      pattern (& (message_buf->data_), data_buf_len);
      prep_timer ();

      ACE_DEBUG ((LM_DEBUG, "Sending session control message"
                  " nbuf %d, size %d\n", session_control_buf.nbuf_,
                  session_control_buf.size_));
      if (connection_stream.send_n ((char *) &session_control_buf,
                                    sizeof (Session_Control_Message))
          != sizeof (Session_Control_Message))
        ACE_ERROR_RETURN ((LM_ERROR,
                           "%p send session control failed\n",
                           "ttcp"),
                          -1);

      long ack;
      int send_result;
      while (nbuf--)
        {
          send_result = connection_stream.send_n ((char *) message_buf,
                                                  total_msg_len);
          if (send_result != total_msg_len)
            ACE_ERROR_RETURN ((LM_ERROR,
                               "%p only sent %d of %d bytes on call %d\n",
                               "ttcp", send_result, total_msg_len, numCalls + 1),
                              -1);
          numCalls++;
          nbytes += data_buf_len;

          if (connection_stream.recv_n ((char *) &ack, sizeof ack) != sizeof ack)
            ACE_ERROR_RETURN ((LM_ERROR, "%p recv of ack failed\n", "ttcp"), -1);

          if (ack != data_buf_len)
            ACE_DEBUG ((LM_DEBUG, "received ack for only %d bytes\n", ack));
        }
      printf("Client finished. \n");
    }
  else
    {
      prep_timer ();

      if (connection_stream.recv_n ((char *) &session_control_buf,
                                    sizeof (Session_Control_Message))

⌨️ 快捷键说明

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