<commit_before>#include <crv.h>
#include <crvAdapt.h>
#include <crvBezier.h>
#include <crvBezierShapes.h>
#include <crvQuality.h>
#include <gmi_analytic.h>
#include <gmi_null.h>
#include <apfMDS.h>
#include <apfMesh2.h>
#include <apf.h>
#include <apfShape.h>
#include <PCU.h>

#include <math.h>
#include <cassert>

class Constant : public ma::IsotropicFunction
{
  public:
    Constant()
    {
    }
    virtual double getValue(ma::Entity* /*v*/)
    {
      return 100.0;
    }
  private:
};

// face areas are 1/2 and 19/30
void vert0(double const p[2], double x[3], void*)
{
  (void)p;
  (void)x;
}
// edges go counter clockwise
void edge0(double const p[2], double x[3], void*)
{
  x[0] = p[0];
  x[1] = p[0]*(p[0]-1.0);
}
void edge1(double const p[2], double x[3], void*)
{
//  x[0] = 1.0-5.0*p[0]*(p[0]-1.0)*p[0]*(p[0]-1.0);
  x[0] = 1.0-p[0]*(p[0]-1.0);
  x[1] = p[0];
}
void edge2(double const p[2], double x[3], void*)
{
  double u = 1.-p[0];
  x[0] = u;
  x[1] = 1.;
}
void edge3(double const p[2], double x[3], void*)
{
  double v = 1.-p[0];
  x[0] = 0;
  x[1] = v;
}

void face0(double const p[2], double x[3], void*)
{
  x[0] = p[0];
  x[1] = p[1];
}
void reparam_zero(double const from[2], double to[2], void*)
{
  (void)from;
  to[0] = 0;
  to[1] = 0;
}
void reparam_one(double const from[2], double to[2], void*)
{
  (void)from;
  to[0] = 1;
  to[1] = 0;
}

agm_bdry add_bdry(gmi_model* m, gmi_ent* e)
{
  return agm_add_bdry(gmi_analytic_topo(m), agm_from_gmi(e));
}

agm_use add_adj(gmi_model* m, agm_bdry b, int tag)
{
  agm* topo = gmi_analytic_topo(m);
  int dim = agm_dim_from_type(agm_bounds(topo, b).type);
  gmi_ent* de = gmi_find(m, dim - 1, tag);
  return agm_add_use(topo, b, agm_from_gmi(de));
}

void make_edge_topo(gmi_model* m, gmi_ent* e, int v0tag, int v1tag)
{
  agm_bdry b = add_bdry(m, e);
  agm_use u0 = add_adj(m, b, v0tag);
  gmi_add_analytic_reparam(m, u0, reparam_zero, 0);
  agm_use u1 = add_adj(m, b, v1tag);
  gmi_add_analytic_reparam(m, u1, reparam_one, 0);
}

gmi_model* makeModel()
{
  gmi_model* model = gmi_make_analytic();
  int edPer = 0;
  double edRan[2] = {0, 1};
  for(int i = 0; i < 4; ++i)
    gmi_add_analytic(model, 0, i, vert0, NULL,NULL,NULL);
  gmi_ent* eds[4];
  eds[0] = gmi_add_analytic(model, 1, 0, edge0, &edPer, &edRan, 0);
  eds[1] = gmi_add_analytic(model, 1, 1, edge1, &edPer, &edRan, 0);
  eds[2] = gmi_add_analytic(model, 1, 2, edge2, &edPer, &edRan, 0);
  eds[3] = gmi_add_analytic(model, 1, 3, edge3, &edPer, &edRan, 0);
  for(int i = 0; i < 4; ++i)
    make_edge_topo(model, eds[i], i, (i+1) % 4);
  int faPer[2] = {0, 0};
  double faRan[2][2] = {{0,1},{0,1}};
  gmi_add_analytic(model, 2, 0, face0, faPer, faRan, 0);

  return model;
}

apf::Mesh2* createMesh2D()
{
  gmi_model* model = makeModel();
  apf::Mesh2* m = apf::makeEmptyMdsMesh(model, 2, false);
  apf::MeshEntity* v[4];
  apf::Vector3 points2D[4] =
  {apf::Vector3(0,0,0),
      apf::Vector3(1,0,0),
      apf::Vector3(1,1,0),
      apf::Vector3(0,1,0)};

  for (int i = 0; i < 4; ++i){
    v[i] = m->createVertex(m->findModelEntity(0,i),points2D[i],points2D[i]);
  }
  for (int i = 0; i < 4; ++i){
    apf::ModelEntity* edge = m->findModelEntity(1,i);
    apf::MeshEntity* ved[2] = {v[i],v[(i+1) % 4]};
    apf::buildElement(m, edge, apf::Mesh::EDGE, ved);
  }

  apf::MeshEntity* ved[2] = {v[0],v[2]};
  apf::buildElement(m, m->findModelEntity(2,0), apf::Mesh::EDGE, ved);

  apf::MeshEntity* vf0[3] = {v[0],v[1],v[2]};
  apf::buildElement(m, m->findModelEntity(2,0), apf::Mesh::TRIANGLE, vf0);
  apf::MeshEntity* vf1[3] = {v[0],v[2],v[3]};
  apf::buildElement(m, m->findModelEntity(2,0), apf::Mesh::TRIANGLE, vf1);
  m->acceptChanges();
  m->verify();
  return m;
}

static double measureMesh(apf::Mesh2* m)
{
  apf::MeshEntity* e;
  apf::MeshIterator* it = m->begin(m->getDimension());
  double v = 0.;
  while ((e = m->iterate(it)))
    v += apf::measure(m,e);

  m->end(it);
  return v;
}

void test2D()
{
  for(int order = 1; order <= 6; ++order){
      apf::Mesh2* m = createMesh2D();
      apf::changeMeshShape(m, crv::getBezier(order),true);
      crv::BezierCurver bc(m,order,0);
      if(order > 1){

      // creates interpolation points based on the edges of the geometry
      bc.snapToInterpolate(1);
      apf::FieldShape* fs = m->getShape();

      // go downward, and convert interpolating to control points
      {
        int n = order+1;
        int ne = fs->countNodesOn(apf::Mesh::EDGE);
        apf::NewArray<double> c;
        crv::getBezierTransformationCoefficients(order,apf::Mesh::EDGE,c);
        apf::MeshEntity* e;
        apf::MeshIterator* it = m->begin(1);
        while ((e = m->iterate(it))) {
          crv::convertInterpolationPoints(m,e,n,ne,c);
        }
        m->end(it);
      }
      if(fs->hasNodesIn(2)) {
        int n = crv::getNumControlPoints(2,order);
        int ne = fs->countNodesOn(apf::Mesh::TRIANGLE);
        apf::NewArray<double> c;
        crv::getInternalBezierTransformationCoefficients(m,order,1,
            apf::Mesh::TRIANGLE,c);
        apf::MeshEntity* e;
        apf::MeshIterator* it = m->begin(2);
        while ((e = m->iterate(it))){
          crv::convertInterpolationPoints(m,e,n-ne,ne,c);
        }
        m->end(it);
      }
      }
      double v0 = measureMesh(m);
      ma::Input* inRefine = ma::configureUniformRefine(m,1);
      inRefine->shouldSnap = true;
      inRefine->shouldTransferParametric = true;
      if(order > 1)
        crv::adapt(inRefine);
      else
        ma::adapt(inRefine);
      double v1 = measureMesh(m);
      if(order > 1){
        assert( std::fabs(v1-v0) < 0.05 );
      }
      m->destroyNative();
      apf::destroyMesh(m);
    }
}

apf::Mesh2* createMesh3D()
{
  gmi_model* model = gmi_load(".null");
  apf::Mesh2* m = apf::makeEmptyMdsMesh(model, 3, false);
  double x = 1./sqrt(6.);
  double z = 1./sqrt(12.);
  apf::Vector3 points3D[4] =
  {apf::Vector3(x,0,-z),
      apf::Vector3(-x,0,-z),
      apf::Vector3(0,-x,z),
      apf::Vector3(0,x,z)};

  apf::buildOneElement(m,0,apf::Mesh::TET,points3D);

  apf::deriveMdsModel(m);

  m->acceptChanges();
  m->verify();
  return m;
}

void test3D()
{
  gmi_register_null();
  // test full
  for(int order = 1; order <= 4; ++order){
    apf::Mesh2* m = createMesh3D();
    crv::BezierCurver bc(m,order,0);
    bc.run();

    double v0 = measureMesh(m);
    ma::Input* inRefine = ma::configureUniformRefine(m,1);
    inRefine->shouldSnap = false;
    inRefine->shouldTransferParametric = false;
    if(order > 1)
      crv::adapt(inRefine);
    else
      ma::adapt(inRefine);
    double v1 = measureMesh(m);
    assert( std::fabs(v1-v0) < 0.05 );

    m->destroyNative();
    apf::destroyMesh(m);
  }
  // test blended
  for(int order = 1; order <= 4; ++order){
    apf::Mesh2* m = createMesh3D();
    crv::BezierCurver bc(m,order,1);
    bc.run();

    double v0 = measureMesh(m);
    ma::Input* inRefine = ma::configureUniformRefine(m,1);
    inRefine->shouldSnap = false;
    inRefine->shouldTransferParametric = false;
    if(order > 1)
      crv::adapt(inRefine);
    else
      ma::adapt(inRefine);
    double v1 = measureMesh(m);
    assert( std::fabs(v1-v0) < 0.05 );

    int numinvalid = crv::countNumberInvalidElements(m);
    assert(numinvalid == 0);

    m->destroyNative();
    apf::destroyMesh(m);
  }

}
int main(int argc, char** argv)
{
  MPI_Init(&argc,&argv);
  PCU_Comm_Init();
  test2D();
  test3D();
  PCU_Comm_Free();
  MPI_Finalize();
}
<commit_msg>removed unused code from bezierRefine test<commit_after>#include <crv.h>
#include <crvAdapt.h>
#include <crvBezier.h>
#include <crvBezierShapes.h>
#include <crvQuality.h>
#include <gmi_analytic.h>
#include <gmi_null.h>
#include <apfMDS.h>
#include <apfMesh2.h>
#include <apf.h>
#include <apfShape.h>
#include <PCU.h>

#include <math.h>
#include <cassert>

// face areas are 1/2 and 19/30
void vert0(double const p[2], double x[3], void*)
{
  (void)p;
  (void)x;
}
// edges go counter clockwise
void edge0(double const p[2], double x[3], void*)
{
  x[0] = p[0];
  x[1] = p[0]*(p[0]-1.0);
}
void edge1(double const p[2], double x[3], void*)
{
//  x[0] = 1.0-5.0*p[0]*(p[0]-1.0)*p[0]*(p[0]-1.0);
  x[0] = 1.0-p[0]*(p[0]-1.0);
  x[1] = p[0];
}
void edge2(double const p[2], double x[3], void*)
{
  double u = 1.-p[0];
  x[0] = u;
  x[1] = 1.;
}
void edge3(double const p[2], double x[3], void*)
{
  double v = 1.-p[0];
  x[0] = 0;
  x[1] = v;
}

void face0(double const p[2], double x[3], void*)
{
  x[0] = p[0];
  x[1] = p[1];
}
void reparam_zero(double const from[2], double to[2], void*)
{
  (void)from;
  to[0] = 0;
  to[1] = 0;
}
void reparam_one(double const from[2], double to[2], void*)
{
  (void)from;
  to[0] = 1;
  to[1] = 0;
}

agm_bdry add_bdry(gmi_model* m, gmi_ent* e)
{
  return agm_add_bdry(gmi_analytic_topo(m), agm_from_gmi(e));
}

agm_use add_adj(gmi_model* m, agm_bdry b, int tag)
{
  agm* topo = gmi_analytic_topo(m);
  int dim = agm_dim_from_type(agm_bounds(topo, b).type);
  gmi_ent* de = gmi_find(m, dim - 1, tag);
  return agm_add_use(topo, b, agm_from_gmi(de));
}

void make_edge_topo(gmi_model* m, gmi_ent* e, int v0tag, int v1tag)
{
  agm_bdry b = add_bdry(m, e);
  agm_use u0 = add_adj(m, b, v0tag);
  gmi_add_analytic_reparam(m, u0, reparam_zero, 0);
  agm_use u1 = add_adj(m, b, v1tag);
  gmi_add_analytic_reparam(m, u1, reparam_one, 0);
}

gmi_model* makeModel()
{
  gmi_model* model = gmi_make_analytic();
  int edPer = 0;
  double edRan[2] = {0, 1};
  for(int i = 0; i < 4; ++i)
    gmi_add_analytic(model, 0, i, vert0, NULL,NULL,NULL);
  gmi_ent* eds[4];
  eds[0] = gmi_add_analytic(model, 1, 0, edge0, &edPer, &edRan, 0);
  eds[1] = gmi_add_analytic(model, 1, 1, edge1, &edPer, &edRan, 0);
  eds[2] = gmi_add_analytic(model, 1, 2, edge2, &edPer, &edRan, 0);
  eds[3] = gmi_add_analytic(model, 1, 3, edge3, &edPer, &edRan, 0);
  for(int i = 0; i < 4; ++i)
    make_edge_topo(model, eds[i], i, (i+1) % 4);
  int faPer[2] = {0, 0};
  double faRan[2][2] = {{0,1},{0,1}};
  gmi_add_analytic(model, 2, 0, face0, faPer, faRan, 0);

  return model;
}

apf::Mesh2* createMesh2D()
{
  gmi_model* model = makeModel();
  apf::Mesh2* m = apf::makeEmptyMdsMesh(model, 2, false);
  apf::MeshEntity* v[4];
  apf::Vector3 points2D[4] =
  {apf::Vector3(0,0,0),
      apf::Vector3(1,0,0),
      apf::Vector3(1,1,0),
      apf::Vector3(0,1,0)};

  for (int i = 0; i < 4; ++i){
    v[i] = m->createVertex(m->findModelEntity(0,i),points2D[i],points2D[i]);
  }
  for (int i = 0; i < 4; ++i){
    apf::ModelEntity* edge = m->findModelEntity(1,i);
    apf::MeshEntity* ved[2] = {v[i],v[(i+1) % 4]};
    apf::buildElement(m, edge, apf::Mesh::EDGE, ved);
  }

  apf::MeshEntity* ved[2] = {v[0],v[2]};
  apf::buildElement(m, m->findModelEntity(2,0), apf::Mesh::EDGE, ved);

  apf::MeshEntity* vf0[3] = {v[0],v[1],v[2]};
  apf::buildElement(m, m->findModelEntity(2,0), apf::Mesh::TRIANGLE, vf0);
  apf::MeshEntity* vf1[3] = {v[0],v[2],v[3]};
  apf::buildElement(m, m->findModelEntity(2,0), apf::Mesh::TRIANGLE, vf1);
  m->acceptChanges();
  m->verify();
  return m;
}

static double measureMesh(apf::Mesh2* m)
{
  apf::MeshEntity* e;
  apf::MeshIterator* it = m->begin(m->getDimension());
  double v = 0.;
  while ((e = m->iterate(it)))
    v += apf::measure(m,e);

  m->end(it);
  return v;
}

void test2D()
{
  for(int order = 1; order <= 6; ++order){
      apf::Mesh2* m = createMesh2D();
      apf::changeMeshShape(m, crv::getBezier(order),true);
      crv::BezierCurver bc(m,order,0);
      if(order > 1){

      // creates interpolation points based on the edges of the geometry
      bc.snapToInterpolate(1);
      apf::FieldShape* fs = m->getShape();

      // go downward, and convert interpolating to control points
      {
        int n = order+1;
        int ne = fs->countNodesOn(apf::Mesh::EDGE);
        apf::NewArray<double> c;
        crv::getBezierTransformationCoefficients(order,apf::Mesh::EDGE,c);
        apf::MeshEntity* e;
        apf::MeshIterator* it = m->begin(1);
        while ((e = m->iterate(it))) {
          crv::convertInterpolationPoints(m,e,n,ne,c);
        }
        m->end(it);
      }
      if(fs->hasNodesIn(2)) {
        int n = crv::getNumControlPoints(2,order);
        int ne = fs->countNodesOn(apf::Mesh::TRIANGLE);
        apf::NewArray<double> c;
        crv::getInternalBezierTransformationCoefficients(m,order,1,
            apf::Mesh::TRIANGLE,c);
        apf::MeshEntity* e;
        apf::MeshIterator* it = m->begin(2);
        while ((e = m->iterate(it))){
          crv::convertInterpolationPoints(m,e,n-ne,ne,c);
        }
        m->end(it);
      }
      }
      double v0 = measureMesh(m);
      ma::Input* inRefine = ma::configureUniformRefine(m,1);
      inRefine->shouldSnap = true;
      inRefine->shouldTransferParametric = true;
      if(order > 1)
        crv::adapt(inRefine);
      else
        ma::adapt(inRefine);
      double v1 = measureMesh(m);
      if(order > 1){
        assert( std::fabs(v1-v0) < 0.05 );
      }
      m->destroyNative();
      apf::destroyMesh(m);
    }
}

apf::Mesh2* createMesh3D()
{
  gmi_model* model = gmi_load(".null");
  apf::Mesh2* m = apf::makeEmptyMdsMesh(model, 3, false);
  double x = 1./sqrt(6.);
  double z = 1./sqrt(12.);
  apf::Vector3 points3D[4] =
  {apf::Vector3(x,0,-z),
      apf::Vector3(-x,0,-z),
      apf::Vector3(0,-x,z),
      apf::Vector3(0,x,z)};

  apf::buildOneElement(m,0,apf::Mesh::TET,points3D);

  apf::deriveMdsModel(m);

  m->acceptChanges();
  m->verify();
  return m;
}

void test3D()
{
  gmi_register_null();
  // test full
  for(int order = 1; order <= 4; ++order){
    apf::Mesh2* m = createMesh3D();
    crv::BezierCurver bc(m,order,0);
    bc.run();

    double v0 = measureMesh(m);
    ma::Input* inRefine = ma::configureUniformRefine(m,1);
    inRefine->shouldSnap = false;
    inRefine->shouldTransferParametric = false;
    if(order > 1)
      crv::adapt(inRefine);
    else
      ma::adapt(inRefine);
    double v1 = measureMesh(m);
    assert( std::fabs(v1-v0) < 0.05 );

    m->destroyNative();
    apf::destroyMesh(m);
  }
  // test blended
  for(int order = 1; order <= 4; ++order){
    apf::Mesh2* m = createMesh3D();
    crv::BezierCurver bc(m,order,1);
    bc.run();

    double v0 = measureMesh(m);
    ma::Input* inRefine = ma::configureUniformRefine(m,1);
    inRefine->shouldSnap = false;
    inRefine->shouldTransferParametric = false;
    if(order > 1)
      crv::adapt(inRefine);
    else
      ma::adapt(inRefine);
    double v1 = measureMesh(m);
    assert( std::fabs(v1-v0) < 0.05 );

    int numinvalid = crv::countNumberInvalidElements(m);
    assert(numinvalid == 0);

    m->destroyNative();
    apf::destroyMesh(m);
  }

}
int main(int argc, char** argv)
{
  MPI_Init(&argc,&argv);
  PCU_Comm_Init();
  test2D();
  test3D();
  PCU_Comm_Free();
  MPI_Finalize();
}
<|endoftext|>


<commit_before>#include "dbn/rbm.hpp"

template<typename RBM>
void test_rbm(){
    RBM rbm;

    std::vector<vector<double>> training;
    rbm.train(training, 10);
}

int main(){
    //Very basic RBM that must compile
    typedef dbn::rbm<dbn::layer<dbn::conf<true, 50, true, false, dbn::DecayType::L2, false, dbn::Type::SIGMOID, dbn::Type::SIGMOID>, 100, 100>> rbm_1;

    //Mix units
    typedef dbn::rbm<dbn::layer<dbn::conf<true, 50, true, false, dbn::DecayType::NONE, false, dbn::Type::GAUSSIAN, dbn::Type::NRLU>, 100, 100>> rbm_2;

    //Sparsity
    typedef dbn::rbm<dbn::layer<dbn::conf<true, 50, true, false, dbn::DecayType::L2, true, dbn::Type::SIGMOID, dbn::Type::SIGMOID>, 100, 100>> rbm_3;

    test_rbm<rbm_1>();
    test_rbm<rbm_2>();
    test_rbm<rbm_3>();

    return 0;
}<commit_msg>More tests<commit_after>#include "dbn/rbm.hpp"

template<typename RBM>
void test_rbm(){
    RBM rbm;

    std::vector<vector<double>> training;
    rbm.train(training, 10);
}

template <typename RBM>
using pcd2_trainer_t = dbn::persistent_cd_trainer<2, RBM>;

int main(){
    //Very basic RBM that must compile
    typedef dbn::rbm<dbn::layer<dbn::conf<true, 50, true, false, dbn::DecayType::L2, false, dbn::Type::SIGMOID, dbn::Type::SIGMOID>, 100, 100>> rbm_1;

    //Mix units
    typedef dbn::rbm<dbn::layer<dbn::conf<true, 50, true, false, dbn::DecayType::NONE, false, dbn::Type::GAUSSIAN, dbn::Type::NRLU>, 100, 100>> rbm_2;

    //Sparsity
    typedef dbn::rbm<dbn::layer<dbn::conf<true, 50, true, false, dbn::DecayType::L2, true, dbn::Type::SIGMOID, dbn::Type::SIGMOID>, 100, 100>> rbm_3;

    //PCD-2

    typedef dbn::rbm<dbn::layer<dbn::conf<true, 50, true, false, dbn::DecayType::NONE, false, dbn::Type::GAUSSIAN, dbn::Type::NRLU, pcd2_trainer_t>, 100, 100>> rbm_4;

    //PCD-2 and sparsity

    typedef dbn::rbm<dbn::layer<dbn::conf<true, 50, true, false, dbn::DecayType::NONE, true, dbn::Type::GAUSSIAN, dbn::Type::SIGMOID, pcd2_trainer_t>, 100, 100>> rbm_5;

    //Test them all

    test_rbm<rbm_1>();
    test_rbm<rbm_2>();
    test_rbm<rbm_3>();
    test_rbm<rbm_4>();
    test_rbm<rbm_5>();

    return 0;
}<|endoftext|>


<commit_before>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 512
#define ACK 0
#define NAK 1
#define BUFSIZE 505
#define FILENAME "Testfile"
#define TIMEOUT 15 //in ms
#define WIN_SIZE 16

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
void loadWindow();
bool sendPacket();
bool getGet();

struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
Packet window[16];
int length;
bool dropPck;
bool delayPck;
int toms;
unsigned char b[BUFSIZE];
int base;

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  if(sendFile()) cout << "GET Testfile complete." << endl;

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 4) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[1];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[2];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[3];
  probDelay = boost::lexical_cast<int>(probDelayStr);

  struct timeval timeout;
  timeout.tv_usec = TIMEOUT * 1000;
  toms = TIMEOUT;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  base = 0;
  dropPck = false;
  calen = sizeof(ca);

  getGet();

  return true;
}

bool getGet(){
	unsigned char packet[PAKSIZE + 1];
	rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
	return (rlen > 0) ? true : false;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == 0) return false; //doesn't matter, only for the old version (netwark)
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        //seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p (false, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

void loadWindow(){
	for(int i = base; i < base + WIN_SIZE; i++) {
		window[i-base] = createPacket(i);
		if(strlen(window[i-base].getDataBuffer()) < BUFSIZE && window[i-base].chksm()) {
			cout << "In loadWindow's secret base, index is: " << i-base << endl;
			for(++i; i < base + WIN_SIZE; i++){
				window[i-base].loadDataBuffer("\0");
			}

		}
		/*cout << "window[i-base] seq. num: " << window[i-base].getSequenceNum() << endl;*/
	}

		/*cout << "packet " << base + 1 << ": " << window[1].str() << endl;
		cout << "packet " << base + 2 << ": " << window[2].str() << endl;*/
}

bool sendFile() {
	/*Currently causes the program to only send the first 16 packets of file out
		requires additional code later to sendFile again with updated window*/
	fd_set stReadFDS;

	struct timeval stTimeOut;

	FD_ZERO(&stReadFDS);
	stTimeOut.tv_sec = 0;
	stTimeOut.tv_usec = 1000 * TIMEOUT;
	FD_SET(s, &stReadFDS);

	base = 0;
	int desc_ready;

	int max_sd;
	bool hasRead = false;
	while(base * BUFSIZE < length) {
		int finale = 0;
		loadWindow();

		if(p.str()[0] == '\0') finale = p.getSequenceNum();
		for(int x = 0; x < WIN_SIZE; x++) {
			p = window[x];
			if(!sendPacket()) continue;
		}
		while(finale < WIN_SIZE - 1) {
			FD_ZERO(&stReadFDS);
			stTimeOut.tv_sec = 0;
			stTimeOut.tv_usec = 1000 * TIMEOUT;
			FD_SET(s, &stReadFDS);

			max_sd = s;
			int t = select(max_sd + 1, &stReadFDS, NULL, NULL, &stTimeOut);
			if (t == -1){
				perror("select()");
			}
			if (t == 0) {
				cout << "=== ACK TIMEOUT (select)" << endl;

			}
			desc_ready = t;
			for(int u = 0; u <= max_sd &&  desc_ready > 0; u++){
				if(finale + desc_ready < WIN_SIZE){
					if(finale++ == WIN_SIZE - 2) break;
				}
				if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
					cout << "=== ACK TIMEOUT (recvfrom)" << endl;
				} else hasRead = true;
				if(!hasRead) continue;
				if(isAck()) {
					handleAck();
					finale++;
					if (finale == WIN_SIZE - 1) break;
				} else {
					cout << "Not an ACK!" << endl;
				}
			}
			/*if(finale > 0 && base == finale) {cout << "Finale: " << finale << endl; break;}
			memset(b, 0, BUFSIZE);
			}*/

		}
	}
	if(sendto(s, "\0", BUFSIZE, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Final package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
	}
	return true;
}

Packet createPacket(int index){
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
		cout << "Null terminated mstr." << endl;
		mstr[length - (index * BUFSIZE)] = '\0';
    }

	cout << "index: " << index << endl;
    return Packet (index, mstr.c_str());
}

bool sendPacket(){
	cout << endl;
    cout << "=== TRANSMISSION START" << endl;
	cout << "Sequence number before gremlin function: " << p.getSequenceNum() << endl;
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) p.setAckNack(1);

    if(sendto(s, p.str(), BUFSIZE + 8, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '\0') return true;
    else return false;
}
void handleAck() {
	int ack = boost::lexical_cast<int>(b);
	if(base < ack) base = ack;
	cout << "Window base: " << base << endl;
}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
	cout << "Seq. num (pre-gremlin): " << pack->getSequenceNum() << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  //cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<commit_msg>Resend as soon as timeout occurs<commit_after>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 512
#define ACK 0
#define NAK 1
#define BUFSIZE 505
#define FILENAME "Testfile"
#define TIMEOUT 15 //in ms
#define WIN_SIZE 16

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
void loadWindow();
bool sendPacket();
bool getGet();

struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
Packet window[16];
int length;
bool dropPck;
bool delayPck;
int toms;
unsigned char b[BUFSIZE];
int base;

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  if(sendFile()) cout << "GET Testfile complete." << endl;

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 4) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[1];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[2];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[3];
  probDelay = boost::lexical_cast<int>(probDelayStr);

  struct timeval timeout;
  timeout.tv_usec = TIMEOUT * 1000;
  toms = TIMEOUT;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  base = 0;
  dropPck = false;
  calen = sizeof(ca);

  getGet();

  return true;
}

bool getGet(){
	unsigned char packet[PAKSIZE + 1];
	rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
	return (rlen > 0) ? true : false;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == 0) return false; //doesn't matter, only for the old version (netwark)
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        //seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p (false, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

void loadWindow(){
	for(int i = base; i < base + WIN_SIZE; i++) {
		window[i-base] = createPacket(i);
		if(strlen(window[i-base].getDataBuffer()) < BUFSIZE && window[i-base].chksm()) {
			cout << "In loadWindow's secret base, index is: " << i-base << endl;
			for(++i; i < base + WIN_SIZE; i++){
				window[i-base].loadDataBuffer("\0");
			}

		}
		/*cout << "window[i-base] seq. num: " << window[i-base].getSequenceNum() << endl;*/
	}

		/*cout << "packet " << base + 1 << ": " << window[1].str() << endl;
		cout << "packet " << base + 2 << ": " << window[2].str() << endl;*/
}

bool sendFile() {
	/*Currently causes the program to only send the first 16 packets of file out
		requires additional code later to sendFile again with updated window*/
	fd_set stReadFDS;

	struct timeval stTimeOut;

	FD_ZERO(&stReadFDS);
	stTimeOut.tv_sec = 0;
	stTimeOut.tv_usec = 1000 * TIMEOUT;
	FD_SET(s, &stReadFDS);

	base = 0;
	int desc_ready;

	int max_sd;
	bool hasRead = false;
	while(base * BUFSIZE < length) {
		int finale = 0;
		loadWindow();

		if(p.str()[0] == '\0') finale = p.getSequenceNum();
		for(int x = 0; x < WIN_SIZE; x++) {
			p = window[x];
			if(!sendPacket()) continue;
		}
		while(finale < WIN_SIZE - 1) {
			FD_ZERO(&stReadFDS);
			stTimeOut.tv_sec = 0;
			stTimeOut.tv_usec = 1000 * TIMEOUT;
			FD_SET(s, &stReadFDS);

			max_sd = s;
			int t = select(max_sd + 1, &stReadFDS, NULL, NULL, &stTimeOut);
			if (t == -1){
				perror("select()");
			}
			if (t == 0) {
				cout << "=== ACK TIMEOUT (select)" << endl;
				break;
			}
			desc_ready = t;
			for(int u = 0; u <= max_sd &&  desc_ready > 0; u++){
				if(finale + desc_ready < WIN_SIZE){
					if(finale++ == WIN_SIZE - 2) break;
				}
				if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
					cout << "=== ACK TIMEOUT (recvfrom)" << endl;
				} else hasRead = true;
				if(!hasRead) continue;
				if(isAck()) {
					handleAck();
					finale++;
					if (finale == WIN_SIZE - 1) break;
				} else {
					cout << "Not an ACK!" << endl;
				}
			}
			/*if(finale > 0 && base == finale) {cout << "Finale: " << finale << endl; break;}
			memset(b, 0, BUFSIZE);
			}*/

		}
	}
	if(sendto(s, "\0", BUFSIZE, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Final package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
	}
	return true;
}

Packet createPacket(int index){
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
		cout << "Null terminated mstr." << endl;
		mstr[length - (index * BUFSIZE)] = '\0';
    }

	cout << "index: " << index << endl;
    return Packet (index, mstr.c_str());
}

bool sendPacket(){
	cout << endl;
    cout << "=== TRANSMISSION START" << endl;
	cout << "Sequence number before gremlin function: " << p.getSequenceNum() << endl;
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) p.setAckNack(1);

    if(sendto(s, p.str(), BUFSIZE + 8, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '\0') return true;
    else return false;
}
void handleAck() {
	int ack = boost::lexical_cast<int>(b);
	if(base < ack) base = ack;
	cout << "Window base: " << base << endl;
}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
	cout << "Seq. num (pre-gremlin): " << pack->getSequenceNum() << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  //cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<|endoftext|>


<commit_before>#pragma once
#ifndef STACKALLOCATOR_HPP
# define STACKALLOCATOR_HPP

#include <cassert>

#include <cstddef>

#include <functional>

#include <new>

#include <utility>

template <std::size_t N>
class stack_store
{
public:
  stack_store() = default;

  stack_store(stack_store const&) = delete;

  stack_store& operator=(stack_store const&) = delete;

  char* allocate(std::size_t n)
  {
    assert(pointer_in_buffer(ptr_) &&
      "stack_allocator has outlived stack_store");

    n = align(n);

    if (buf_ + N >= ptr_ + n)
    {
      auto r(ptr_);

      ptr_ += n;

      return r;
    }
    else
    {
      return static_cast<char*>(::operator new(n));
    }
  }

  void deallocate(char* const p, std::size_t n) noexcept
  {
    assert(pointer_in_buffer(ptr_) &&
      "stack_allocator has outlived stack_store");

    if (pointer_in_buffer(p))
    {
      n = align(n);

      if (p + n == ptr_)
      {
        ptr_ = p;
      }
      // else do nothing
    }
    else
    {
      ::operator delete(p);
    }
  }

  void reset() noexcept { ptr_ = buf_; }

  static constexpr ::std::size_t size() noexcept { return N; }

  ::std::size_t used() const { return ::std::size_t(ptr_ - buf_); }

private:
  static constexpr ::std::size_t align(::std::size_t const n) noexcept
  {
    return (n + (alignment - 1)) & -alignment;
  }

  bool pointer_in_buffer(char* const p) noexcept
  {
    return (buf_ <= p) && (p <= buf_ + N);
  }

private:
  static constexpr auto const alignment = alignof(::max_align_t);

  char* ptr_{buf_};

  alignas(::max_align_t) char buf_[N];
};

template <class T, std::size_t N>
class stack_allocator
{
public:
  using store_type = stack_store<N>;

  using size_type = ::std::size_t;

  using difference_type = ::std::ptrdiff_t;

  using pointer = T*;
  using const_pointer = T const*;

  using reference = T&;
  using const_reference = T const&;

  using value_type = T;

  template <class U> struct rebind { using other = stack_allocator<U, N>; };

  stack_allocator() = default;

  stack_allocator(stack_store<N>& s) noexcept : store_(&s) { }

  template <class U>
  stack_allocator(stack_allocator<U, N> const& other) noexcept :
    store_(other.store_)
  {
  }

  stack_allocator& operator=(stack_allocator const&) = delete;

  T* allocate(::std::size_t const n)
  {
    return static_cast<T*>(static_cast<void*>(
      store_->allocate(n * sizeof(T))));
  }

  void deallocate(T* const p, ::std::size_t const n) noexcept
  {
    store_->deallocate(static_cast<char*>(static_cast<void*>(p)),
      n * sizeof(T));
  }

  template <class U, class ...A>
  void construct(U* p, A&& ...args)
  {
    new (p) U(::std::forward<A>(args)...);
  }

  template <class U>
  void destroy(U* const p)
  {
    p->~U();
  }

  template <class U, std::size_t M>
  inline bool operator==(stack_allocator<U, M> const& rhs) const noexcept
  {
    return store_ == rhs.store_;
  }

  template <class U, std::size_t M>
  inline bool operator!=(stack_allocator<U, M> const& rhs) const noexcept
  {
    return !(*this == rhs);
  }

private:
  template <class U, std::size_t M> friend class stack_allocator;

  store_type* store_{};
};

namespace std
{
  // string
  template<class CharT> class char_traits;

  template<class CharT, class Traits, class Allocator> class basic_string;

  // unordered_map
  template<class Key, class T, class Hash, class Pred, class Alloc>
    class unordered_map;

  // vector
  template <class T, class Alloc> class vector;
}

using stack_string = ::std::basic_string<char, ::std::char_traits<char>,
  stack_allocator<char, 128> >;

template <class Key, class T, class Hash = ::std::hash<Key>,
  class Pred = ::std::equal_to<Key> >
using stack_unordered_map = ::std::unordered_map<Key, T, Hash, Pred,
  stack_allocator<::std::pair<Key const, T>, 256> >;

template <typename T>
using stack_vector = ::std::vector<T, stack_allocator<T, 256> >;

#endif // STACKALLOCATOR_HPP
<commit_msg>strips<commit_after>#pragma once
#ifndef STACKALLOCATOR_HPP
# define STACKALLOCATOR_HPP

#include <cassert>

#include <cstddef>

#include <functional>

#include <new>

#include <utility>

template <std::size_t N>
class stack_store
{
public:
  stack_store() = default;

  stack_store(stack_store const&) = delete;

  stack_store& operator=(stack_store const&) = delete;

  char* allocate(std::size_t n)
  {
    assert(pointer_in_buffer(ptr_) &&
      "stack_allocator has outlived stack_store");

    n = align(n);

    if (buf_ + N >= ptr_ + n)
    {
      auto r(ptr_);

      ptr_ += n;

      return r;
    }
    else
    {
      return static_cast<char*>(::operator new(n));
    }
  }

  void deallocate(char* const p, std::size_t n) noexcept
  {
    assert(pointer_in_buffer(ptr_) &&
      "stack_allocator has outlived stack_store");

    if (pointer_in_buffer(p))
    {
      n = align(n);

      if (p + n == ptr_)
      {
        ptr_ = p;
      }
      // else do nothing
    }
    else
    {
      ::operator delete(p);
    }
  }

  void reset() noexcept { ptr_ = buf_; }

  static constexpr ::std::size_t size() noexcept { return N; }

  ::std::size_t used() const { return ::std::size_t(ptr_ - buf_); }

private:
  static constexpr ::std::size_t align(::std::size_t const n) noexcept
  {
    return (n + (alignment - 1)) & -alignment;
  }

  bool pointer_in_buffer(char* const p) noexcept
  {
    return (buf_ <= p) && (p <= buf_ + N);
  }

private:
  static constexpr auto const alignment = alignof(::max_align_t);

  char* ptr_{buf_};

  alignas(::max_align_t) char buf_[N];
};

template <class T, std::size_t N>
class stack_allocator
{
public:
  using store_type = stack_store<N>;

  using size_type = ::std::size_t;

  using difference_type = ::std::ptrdiff_t;

  using pointer = T*;
  using const_pointer = T const*;

  using reference = T&;
  using const_reference = T const&;

  using value_type = T;

  template <class U> struct rebind { using other = stack_allocator<U, N>; };

  stack_allocator() = default;

  stack_allocator(stack_store<N>& s) noexcept : store_(&s) { }

  template <class U>
  stack_allocator(stack_allocator<U, N> const& other) noexcept :
    store_(other.store_)
  {
  }

  stack_allocator& operator=(stack_allocator const&) = delete;

  T* allocate(::std::size_t const n)
  {
    return static_cast<T*>(static_cast<void*>(
      store_->allocate(n * sizeof(T))));
  }

  void deallocate(T* const p, ::std::size_t const n) noexcept
  {
    store_->deallocate(static_cast<char*>(static_cast<void*>(p)),
      n * sizeof(T));
  }

  template <class U, class ...A>
  void construct(U* const p, A&& ...args)
  {
    new (p) U(::std::forward<A>(args)...);
  }

  template <class U>
  void destroy(U* const p)
  {
    p->~U();
  }

  template <class U, std::size_t M>
  inline bool operator==(stack_allocator<U, M> const& rhs) const noexcept
  {
    return store_ == rhs.store_;
  }

  template <class U, std::size_t M>
  inline bool operator!=(stack_allocator<U, M> const& rhs) const noexcept
  {
    return !(*this == rhs);
  }

private:
  template <class U, std::size_t M> friend class stack_allocator;

  store_type* store_{};
};

namespace std
{
  // string
  template<class CharT> class char_traits;

  template<class CharT, class Traits, class Allocator> class basic_string;

  // unordered_map
  template<class Key, class T, class Hash, class Pred, class Alloc>
    class unordered_map;

  // vector
  template <class T, class Alloc> class vector;
}

using stack_string = ::std::basic_string<char, ::std::char_traits<char>,
  stack_allocator<char, 128> >;

template <class Key, class T, class Hash = ::std::hash<Key>,
  class Pred = ::std::equal_to<Key> >
using stack_unordered_map = ::std::unordered_map<Key, T, Hash, Pred,
  stack_allocator<::std::pair<Key const, T>, 256> >;

template <typename T>
using stack_vector = ::std::vector<T, stack_allocator<T, 256> >;

#endif // STACKALLOCATOR_HPP
<|endoftext|>


<commit_before>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 512
#define ACK 0
#define NAK 1
#define BUFSIZE 505
#define FILENAME "Testfile"
#define TIMEOUT 15 //in ms
#define WIN_SIZE 16

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
void loadWindow();
bool sendPacket();
bool getGet();

struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
Packet window[16];
int length;
bool dropPck;
bool delayPck;
int toms;
unsigned char b[BUFSIZE];
int base;

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  if(sendFile()) cout << "GET Testfile complete." << endl;

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  struct timeval timeout;
  timeout.tv_usec = TIMEOUT * 1000;
  toms = TIMEOUT;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  base = 0;
  dropPck = false;
  calen = sizeof(ca);

  getGet();

  return true;
}

bool getGet(){
	unsigned char packet[PAKSIZE + 1];
	rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
	return (rlen > 0) ? true : false;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == 0) return false; //doesn't matter, only for the old version (netwark)
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        //seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p (false, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

void loadWindow(){
	for(int i = base; i < base + WIN_SIZE; i++) {
		window[i-base] = createPacket(i);
		if(strlen(window[i-base].getDataBuffer()) < BUFSIZE && window[i-base].chksm()) {
			cout << "In loadWindow's secret base, index is: " << i-base << endl;
			for(++i; i < base + WIN_SIZE; i++){
				window[i-base].loadDataBuffer("\0");
			}

		}
		/*cout << "window[i-base] seq. num: " << window[i-base].getSequenceNum() << endl;*/
	}

		/*cout << "packet " << base + 1 << ": " << window[1].str() << endl;
		cout << "packet " << base + 2 << ": " << window[2].str() << endl;*/
}

bool sendFile() {
	/*Currently causes the program to only send the first 16 packets of file out
		requires additional code later to sendFile again with updated window*/
	fd_set stReadFDS;
	struct timeval stTimeOut;

	FD_ZERO(&stReadFDS);
	stTimeOut.tv_sec = 0;
	stTimeOut.tv_usec = 1000 * TIMEOUT;
	FD_SET(0, &stReadFDS);

	base = 0;
	int finale = -1;
	bool hasRead = false;
	while(base * BUFSIZE < length) {
		loadWindow();

		if(p.str()[0] == '\0') finale = p.getSequenceNum();
		for(int x = 0; x < WIN_SIZE; x++) {
			p = window[x];
			if(!sendPacket()) continue;
		}
		for(int x = 0; x < WIN_SIZE; x++) {
			cout << endl << "beginning of loop " << x << endl;
			FD_ZERO(&stReadFDS);
			stTimeOut.tv_sec = 0;
			stTimeOut.tv_usec = 1000 * TIMEOUT;
			FD_SET(s, &stReadFDS);
			cout << endl << "before select" << endl;
			int t = select(-1, &stReadFDS, NULL, NULL, &stTimeOut);
			if (t == -1){
				perror("select()");
			}
			else if (t) {
				if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
					cout << "=== ACK TIMEOUT (recvfrom)" << endl;
				} else hasRead = true;
			} else {
				cout << "=== ACK TIMEOUT (select)" << endl;
			}
			if(!hasRead) continue;
			if(isAck()) {
				handleAck();
			} else {
				handleAck();
				//handleNak(x);
			}
			cout << "end of loop " << x << endl;
			if(finale > 0 && base == finale) {cout << "Finale: " << finale << endl; break;}
			memset(b, 0, BUFSIZE);
		}

	}

	if(sendto(s, "\0", BUFSIZE, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Final package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
	}
	return true;
}

Packet createPacket(int index){
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
		cout << "Null terminated mstr." << endl;
		mstr[length - (index * BUFSIZE)] = '\0';
    }

	cout << "index: " << index << endl;
    return Packet (index, mstr.c_str());
}

bool sendPacket(){
	cout << endl;
    cout << "=== TRANSMISSION START" << endl;
	cout << "Sequence number before gremlin function: " << p.getSequenceNum() << endl;
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) p.setAckNack(1);

    if(sendto(s, p.str(), BUFSIZE + 8, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {
	int ack = boost::lexical_cast<int>(b);
	if(base < ack) base = ack;
	cout << "Window base: " << base << endl;
}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
	cout << "Seq. num (pre-gremlin): " << pack->getSequenceNum() << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  //cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<commit_msg>trying new parameters<commit_after>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 512
#define ACK 0
#define NAK 1
#define BUFSIZE 505
#define FILENAME "Testfile"
#define TIMEOUT 15 //in ms
#define WIN_SIZE 16

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
void loadWindow();
bool sendPacket();
bool getGet();

struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
Packet window[16];
int length;
bool dropPck;
bool delayPck;
int toms;
unsigned char b[BUFSIZE];
int base;

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  if(sendFile()) cout << "GET Testfile complete." << endl;

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  struct timeval timeout;
  timeout.tv_usec = TIMEOUT * 1000;
  toms = TIMEOUT;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  base = 0;
  dropPck = false;
  calen = sizeof(ca);

  getGet();

  return true;
}

bool getGet(){
	unsigned char packet[PAKSIZE + 1];
	rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
	return (rlen > 0) ? true : false;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == 0) return false; //doesn't matter, only for the old version (netwark)
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        //seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p (false, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

void loadWindow(){
	for(int i = base; i < base + WIN_SIZE; i++) {
		window[i-base] = createPacket(i);
		if(strlen(window[i-base].getDataBuffer()) < BUFSIZE && window[i-base].chksm()) {
			cout << "In loadWindow's secret base, index is: " << i-base << endl;
			for(++i; i < base + WIN_SIZE; i++){
				window[i-base].loadDataBuffer("\0");
			}

		}
		/*cout << "window[i-base] seq. num: " << window[i-base].getSequenceNum() << endl;*/
	}

		/*cout << "packet " << base + 1 << ": " << window[1].str() << endl;
		cout << "packet " << base + 2 << ": " << window[2].str() << endl;*/
}

bool sendFile() {
	/*Currently causes the program to only send the first 16 packets of file out
		requires additional code later to sendFile again with updated window*/
	fd_set stReadFDS;
	struct timeval stTimeOut;

	FD_ZERO(&stReadFDS);
	stTimeOut.tv_sec = 0;
	stTimeOut.tv_usec = 1000 * TIMEOUT;
	FD_SET(0, &stReadFDS);

	base = 0;
	int finale = -1;
	bool hasRead = false;
	while(base * BUFSIZE < length) {
		loadWindow();

		if(p.str()[0] == '\0') finale = p.getSequenceNum();
		for(int x = 0; x < WIN_SIZE; x++) {
			p = window[x];
			if(!sendPacket()) continue;
		}
		for(int x = 0; x < WIN_SIZE; x++) {
			cout << endl << "beginning of loop " << x << endl;
			FD_ZERO(&stReadFDS);
			stTimeOut.tv_sec = 0;
			stTimeOut.tv_usec = 1000 * TIMEOUT;
			FD_SET(0, &stReadFDS);
			cout << endl << "before select" << endl;
			int t = select(1, &stReadFDS, NULL, NULL, &stTimeOut);
			if (t == -1){
				perror("select()");
			}
			else if (t) {
				if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
					cout << "=== ACK TIMEOUT (recvfrom)" << endl;
				} else hasRead = true;
			} else {
				cout << "=== ACK TIMEOUT (select)" << endl;
			}
			if(!hasRead) continue;
			if(isAck()) {
				handleAck();
			} else {
				handleAck();
				//handleNak(x);
			}
			cout << "end of loop " << x << endl;
			if(finale > 0 && base == finale) {cout << "Finale: " << finale << endl; break;}
			memset(b, 0, BUFSIZE);
		}

	}

	if(sendto(s, "\0", BUFSIZE, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Final package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
	}
	return true;
}

Packet createPacket(int index){
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
		cout << "Null terminated mstr." << endl;
		mstr[length - (index * BUFSIZE)] = '\0';
    }

	cout << "index: " << index << endl;
    return Packet (index, mstr.c_str());
}

bool sendPacket(){
	cout << endl;
    cout << "=== TRANSMISSION START" << endl;
	cout << "Sequence number before gremlin function: " << p.getSequenceNum() << endl;
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) p.setAckNack(1);

    if(sendto(s, p.str(), BUFSIZE + 8, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {
	int ack = boost::lexical_cast<int>(b);
	if(base < ack) base = ack;
	cout << "Window base: " << base << endl;
}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
	cout << "Seq. num (pre-gremlin): " << pack->getSequenceNum() << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  //cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<|endoftext|>


<commit_before>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1
#define BUFSIZE 121
#define FILENAME "Testfile"
#define TIMEOUT 100 //in ms

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
bool sendPacket();

bool seqNum = true;
struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
int length;
bool dropPck;
bool delayPck;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  calen = sizeof(ca);

  unsigned char packet[PAKSIZE + 1];
  rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

  sendFile();

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  struct timeval timeout;
  timeout.tv_usec = TIMEOUT * 1000;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  seqNum = true;
  dropPck = false;

  return true;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == seqNum) return false;
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  bool isSeqNumSet = false;
  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
    if(!isSeqNumSet) {
      isSeqNumSet = true;
      char * str = new char[1];
      memcpy(str, &packet[0], 1);
      seqNum = boost::lexical_cast<int>(str);
    }
    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p ((seqNum) ? false : true, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= (length / BUFSIZE) + 1; x++) {
    p = createPacket(x);

	struct timeval t1, t2;
	gettimeofday(&t1, NULL);

    if(!sendPacket()) continue;

    if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
		cout << "=== ACK TIMEOUT" << endl;
		x--;
		continue;
	}

	gettimeofday(&t2, NULL);
	cout << "We took " << (t2.tv_usec - t1.tv_usec)/1000 << " ms to receive that ack." << endl;
	cout << "We had " << timeout.tv_usec/1000 << " ms to take." << endl;

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) usleep(delayT * 1000); //using milliseconds

    if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
	  seqNum = (seqNum) ? false : true;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<commit_msg>Fix testing for timer<commit_after>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1
#define BUFSIZE 121
#define FILENAME "Testfile"
#define TIMEOUT 100 //in ms

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
bool sendPacket();

bool seqNum = true;
struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
int length;
bool dropPck;
bool delayPck;
struct timeval timeout;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  calen = sizeof(ca);

  unsigned char packet[PAKSIZE + 1];
  rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

  sendFile();

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  timeout.tv_usec = TIMEOUT * 1000;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  seqNum = true;
  dropPck = false;

  return true;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == seqNum) return false;
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  bool isSeqNumSet = false;
  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
    if(!isSeqNumSet) {
      isSeqNumSet = true;
      char * str = new char[1];
      memcpy(str, &packet[0], 1);
      seqNum = boost::lexical_cast<int>(str);
    }
    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p ((seqNum) ? false : true, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= (length / BUFSIZE) + 1; x++) {
    p = createPacket(x);

	struct timeval t1, t2;
	gettimeofday(&t1, NULL);

    if(!sendPacket()) continue;

    if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
		cout << "=== ACK TIMEOUT" << endl;
		x--;
		continue;
	}

	gettimeofday(&t2, NULL);
	cout << "We took " << (t2.tv_usec - t1.tv_usec)/1000 << " ms to receive that ack." << endl;
	cout << "We had " << timeout.tv_usec/1000 << " ms to take." << endl;

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) usleep(delayT * 1000); //using milliseconds

    if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
	  seqNum = (seqNum) ? false : true;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<|endoftext|>