Can anyone help me out?

From: Adie (a_usenetizen_at_hotmail.com)
Date: 05/04/03


Date: Sun, 04 May 2003 17:42:28 +0100

I have some socket code that transfers a file from one machine to another.
It has been ran and tested up to now on the loopback of my Mandrake Linux
machine, but the code has to run between a Linux and Sun Solaris Sparc
machine, but I have no access to one to test.

I know this is a weird request, but can anyone who has a sparc machine and a
linux machine try and complie and run my code?

It takes a command line argument of a filename and an IP from the client.

I want to test it because i'm using "strings" and am not sure if I need to
do any network byte ordering.

There are five files
fileIO.cpp -- Main for client
client.h - client file transfer
SvrFileIO.cpp Main for server
server.h - server file transfer
packet.h - builds packets

server must be ran first.

/***************************************************************************
                          fileIO.cpp -- Main for client

***************************************************************************/

#include <string>
#include <iostream>
#include <fstream>
#include "client.h"

#define MAXPACKET 1501

using std::ifstream;
using namespace std;

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

Client client;
string tmp = "";
char foo[MAXPACKET] = {0};
string fname;
long fsize;

/*parse argv and argc*/
if (!argv[1])
{
  cout << "\nError, need filename\n";
  exit(1);
}

if (!argv[2])
{
  cout << "\nError, need server IP\n";
  exit(1);
}

/* create ifstream class */
ifstream MyFile(argv[1], ios_base::binary);

/* test if file exists */
if (!MyFile)
{
    cout<<"FILE " << fname.c_str() << " " << client.FileName() << " NOT
FOUND. TERMINATING";
    return 1;
}

/* get the file size */
MyFile.seekg(0, ios::end);
fsize=MyFile.tellg();
client.FileSize(MyFile.tellg());
MyFile.seekg (0,ios::beg);

client.FileName(argv[1]);
client.ServerIP(argv[2]);

if (client.Connect() == false)
{
    cout<<"\n\nERROR CANNOT CONNECT TO " << client.ServerIP();
    exit(1);
}

   while(fsize > 0 )
   {
       tmp="";
       if (fsize < 1000)
       {
         MyFile.read(foo,fsize);
         tmp.assign(foo,fsize);
         fsize = 0;
       }
       else
       {
         MyFile.read(foo,1000);
         tmp.assign(foo,1000);
         fsize = fsize - tmp.length();
        }
        memset(foo,0,1000);
        //cout<<fsize<<" end loop\n ";//<< tmp;
        client.Data(tmp,tmp.length());
         //i++;
   }

/* close file */
MyFile.close();

return 0;

}

/***************************************************************************
                          client.h - description

***************************************************************************/

/* c++ libs */
#include <string>
#include <iostream>
#include <vector>
#include <sstream>
#include "packet.h"

/* c libs */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <arpa/inet.h>
#include <unistd.h>

//#include "clientpacket.h"
using namespace std;

extern int errno;
#define MAXBUFFER 1501 /*maximum packet data size */

class Client {

public:

Client();

bool Connect();
void Data (string &arg,int bufsize);

inline void FileSize (long fsize){filesize = fsize;}
inline long FileSize (void){return filesize;}

int Msg(void){return msg;}
int ServerMsg(void);
string Data(void) {return data;}

inline void ServerIP(string sIP){serverIP = sIP;}
inline string ServerIP(void){return serverIP;}

//inline string FileName (void){return filename.c_str();}
inline string FileName (void){return filename;}
inline void FileName (string fname){filename = fname;}

private:

void Transport (string &arg,int bufsize);
inline int GetSkt(void){return sktRemote;}
inline void SetSkt(int sktARG){sktRemote = sktARG;}
//long packet;
string serverIP; /* IP */
string filename; /* filesize */
long filesize, tmpfilesize; /* filename */
string data; /* data */
int msg; /*control messages*/

Packet *packet;

int sktRemote, sktLocal;/*local socket */
struct sockaddr_in client;
struct sockaddr_in server;
struct hostent *hp;

};

Client::Client()
{
/* initiate everything to zero */

serverIP = "";
filename = "";
filesize = 0;
data = "";
bzero(&client,sizeof(client));
bzero(&server,sizeof(server));
}

void Client::Data(string &dataIN, int bufsize)
{
Packet *packet = new Packet;
//cout<<"\n"<<dataIN;
if (packet->package(dataIN,dataIN.length()) != true)
{
    cout << "ERROR CREATING PACKET";
    exit(1);
}
    Transport(dataIN,dataIN.length());
    
if (bufsize < 1000)
{
    if (packet->package(dataIN) != true)
    {
        cout << "ERROR CREATING LAST PACKET";
        exit(1);
    }
    Transport(dataIN,dataIN.length());
}

}

bool Client::Connect()
{
string tmp;
long tmpl;
string buffer = "";
Packet *packet = new Packet;
packet->package(filename, filesize, buffer);
Transport(buffer,buffer.length());
//cout<<buffer;

if (packet->extract(tmp,tmpl,buffer) == true)
{
    return true;
}
else
{
    return false;
}
}
void Client::Transport(string &dataIN, int bufsize)
{

Packet *packet = new Packet;
char dataArrival[1500];
int countServer;

SetSkt(socket(AF_INET,SOCK_DGRAM,0));

if (GetSkt() == -1) {
        cout<<"error creating socket"<<endl;
        exit(1100);/* cant create socket, error */
}
// listening here//
client.sin_addr.s_addr = inet_addr("127.0.0.1");
client.sin_port = htons(4050);
client.sin_family = AF_INET;

//sending here//
server.sin_addr.s_addr = inet_addr((char *) &serverIP);
server.sin_port = htons(4051);
server.sin_family = AF_INET;

if (bind(GetSkt(),(struct sockaddr *) &client,sizeof(client)) == -1) {
        cout<<"\n Wont bind";
        exit(1200);/*errror, socket wont bind*/
}

hp=gethostbyname("localhost");
bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
cout<<dataIN.length()<<" end loop\n ";//<< tmp;
if (sendto(GetSkt(), dataIN.data(), dataIN.length(),0,(struct
sockaddr*)&server,sizeof(struct sockaddr_in)) == -1)
{
  cout<<" error sending ";
  exit(1300);
}

socklen_t length = sizeof(client);

countServer = recvfrom(GetSkt(), dataArrival ,sizeof(dataArrival),0,(struct
sockaddr*)&server,&length);

dataIN.assign(dataArrival, countServer);
//
//cout<<"\n\n\n FROM SERVER ----> " << dataIN << " <----\n";

if (countServer == -1)
{
  cout<<"\nerror recieving messages\n";
}

//cout << " HERE ";

close(GetSkt());

}

/***************************************************************************
                          SvrFileIO.cpp Main for server

***************************************************************************/

#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include "server.h"
#include <iomanip>
#include <cstring>
//#include <iterator>
using namespace std;

#define MAXPACKET 1500

int main(int argc, char **argv)
{
  
string buffer = "";
string fname = "";
long fsize = 0;
Server* server = new Server;

if (server->Connect(fsize,fname) == true)
{
cout<< "\n connection is true\n";

}
else
{
  cout<<"\n ERROR - NO FILENAME OR FILESIZE\n";
  exit(1);
}

fstream MyFile(fname.c_str(), ios_base::out|ios_base::binary);
cout<< "\nfilesize is " << fsize << " filename is " << fname << " buffer is
" << buffer; ;

while (server->Data(buffer) == true)

{
   MyFile.write(buffer.data(),buffer.length());
}

//MyFile.write(buffer.data(),buffer.length());

MyFile.close();
return 0;

}

/***************************************************************************
                          server.h - description

***************************************************************************/

/* c++ libs */
#include <string>
#include <iostream>
#include <sstream>
#include "packet.h"
/* c libs */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <arpa/inet.h>
#include <unistd.h>

using namespace std;

extern int errno;
#define MAXBUFFER 1500 /*maximum packet data size */

class Server {

public:

Server();

bool Connect(long &fsize,string &fname);
bool Data (string &buffer);
inline void ServerIP(string sIP){serverIP = sIP;}
inline string ServerIP(void){return serverIP;}

private:

Packet *packet;
void Transport (string &arg, long &bufsize);
inline int GetSkt(void){return skt;}
inline void SetSkt(int sktARG){skt = sktARG;}
string serverIP; /* IP */
char* filename; /* filesize */
long filesize, tmpfilesize; /* filename */

int skt, sktLocal;/*local socket */
struct sockaddr_in client;
struct sockaddr_in server;
struct hostent *hp;

};

Server::Server()
{
/* initiate everything to zero */
skt = 0;

serverIP = "";
filename = 0;
filesize = 0;
//data = "";
bzero(&client,sizeof(client));
bzero(&server,sizeof(server));
}

bool Server::Connect(long &fsize,string &fname)
{
long bufferSize = 0;
string buffer = "";
Packet *packet = new Packet;
bufferSize = buffer.length();
// check the transport for the connection from a client
Transport(buffer, bufferSize);
// extract the filename and filesize from the packet
if (packet->extract(fname,fsize,buffer) == true)
{
    cout<<" connect true "<< fsize;
    return true;
}
else
{
    return false;
}
}

bool Server::Data(string &buffer)
{

string s = "";
long bufferSize = 0;

bufferSize = buffer.length();
Transport(buffer,bufferSize);

if (packet->extract(s,bufferSize,buffer) == true)
{
    //cout<<"\n"<<bufferSize<<"\n"<<buffer;
    cout<<"\n packet extracted = true "<< bufferSize;
    return true;
}
else
{
    cout<<"\n false "<< bufferSize;
    return false;
}
  
}

void Server::Transport(string &dataIN, long &bufsize)
{

string tmp = "";
//Packet *packet = new Packet;

long countServer = 0;
char dataArrival[1500];
//string data("");

SetSkt(socket(AF_INET,SOCK_DGRAM,0));

if (GetSkt() == -1) {
        cout<<"error creating socket"<<endl;
        exit(1100);/* cant create socket, error */
}

// set up the lisetining server//
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(4051);
server.sin_family = AF_INET;

// set up the potential client to revieve from//
client.sin_addr.s_addr = inet_addr("127.0.0.1");
client.sin_port = htons(4050);
client.sin_family = AF_INET;

if (bind(GetSkt(),(struct sockaddr *) &server,sizeof(server)) == -1) {
        cout<<"\n Wont bind";
        exit(1200);/*errror, socket wont bind*/
}

socklen_t length = sizeof(client);
countServer = recvfrom(GetSkt(), dataArrival ,sizeof(dataArrival),0,(struct
sockaddr*) &client,&length);

if (countServer == -1)
{
  cout<<"\nerror recieving messages\n";
}

dataIN.assign(dataArrival, countServer);
bufsize = countServer;

cout<<"\n\n countserver: "<< countServer;

if (sendto(GetSkt(), dataIN.data(), dataIN.length(),0,(struct
sockaddr*)&client,sizeof(struct sockaddr_in)) == -1) {
    cout<<" error sending ";
    exit(1300);
}

close(GetSkt());

}

                           
/***************************************************************************
                          packet.h - description

***************************************************************************/

#ifndef PACKET_H
#define PACKET_H

#include <string>
#include <iostream>
#include <sstream>
#include <stdlib.h>
using namespace std;

/* declare consts */
const string DELIMITER = "/";
const string CONNECT = "con" + DELIMITER;
const string DATA = "dat" + DELIMITER;
const string TERMINATE = "end" + DELIMITER;
const string ACK = "ack" + DELIMITER;
const unsigned int HEADER_SIZE = 4; // header size
const unsigned int MAXPACKET = 1500;

class Packet
{

public:

Packet(){seq = 0; seq1 = 0; protocol_message = ""; }
bool extract(string &arg1, long &arg2, string &buffer);
bool package(string fname, long fsize, string &buffer);
bool package(string &buffer, int bufsize);

private:
/* last packet. Called from: bool package(string &buffer, int bufsize); */
bool package(string &buffer);
/* sequence number */
unsigned long seq;
unsigned long seq1;
/* protocol errors */
string protocol_message;

};

bool Packet::extract(string &arg1, long &arg2, string &buffer)
{

long tmpbufsize = 0, offset = 0, headerseq = 0;
string message = "",tmpSequence = "";
string headertype,tmp;
int pos_of_delimeter;
headertype = buffer.substr(0,4);

cout<<"\n " << headertype;

/* find out what type of header it is */
if (headertype == CONNECT)
{

    /* delete the header */
    buffer.erase(0,HEADER_SIZE);
    /* find first delimiter */
    pos_of_delimeter = buffer.find(DELIMITER);
    /*delete the filename and assign */
    arg1 = buffer.substr(0,pos_of_delimeter);
    buffer.erase(0,pos_of_delimeter + 1);
    /* find next delimeter */
    pos_of_delimeter = buffer.find(DELIMITER);
    /* assign and delete the file size */
    tmp = buffer.substr(0,pos_of_delimeter);
    arg2 = atol(tmp.c_str());
    /* now at the data */
    buffer.erase(0,pos_of_delimeter + 1);
    return true;

}
else if (headertype == DATA )
{

    //seq1++;
    /* delete the header */
    buffer.erase(0,HEADER_SIZE);
    /* increment the offset value that holds
    the number of characters taken up by the header */
    offset = HEADER_SIZE;
 
    /* find first delimiter */
    pos_of_delimeter = buffer.find(DELIMITER);

    /*assign the sequence from the header */
    tmpSequence = buffer.substr(0,pos_of_delimeter);
    /* convert to a long */
    headerseq = atol(tmpSequence.c_str());
    buffer.erase(0,pos_of_delimeter + DELIMITER.length());

    /* add the characters to offset taken up by the sequence number and
delimeter */
    offset = offset + (pos_of_delimeter + DELIMITER.length());

    /* find next delimeter for buffer size indicated in the header */
    pos_of_delimeter = buffer.find(DELIMITER);

    /* assign and delete the buffer size*/
    tmp = buffer.substr(0,pos_of_delimeter);

    /* convert buffersize indicated in packet header to int */
    tmpbufsize = atol(tmp.c_str());

    /* add the characters to offset taken up by the buffer size and
delimeter */
    offset = offset + (pos_of_delimeter + DELIMITER.length());

    /* now check that buffer size recieved in total
    which is stored in arg2 will match buffersize that
    packet header indicates */

    if (tmpbufsize != (arg2 - offset))
    {
        protocol_message = "DATA IS CORRUPT OR MISSING - QUITING \n";
        cout << protocol_message;
        return false;
    }
    cout << "\n tmpbufsize " << tmpbufsize;
    /* now at the data */
    buffer.erase(0,pos_of_delimeter + DELIMITER.length());
    return true;
}

else if (headertype == TERMINATE)
{
    buffer.erase();
    return false;
}

else
{
    cout << "\n" << headertype << " ERROR -- HEADER IS MALFORMED " <<buffer
<<"\n";
    return false;
}

}

/*------------------------------------------------
    build packet for sending the connect request
--------------------------------------------------*/
bool Packet::package(string fname, long fsize, string &buffer)
{

string temp;
string connect;
ostringstream ostrFileSize;

/* convert filesize to string */
ostrFileSize << fsize;
/* build the connection header */
connect += CONNECT;
connect += fname; // filename being sent
connect += DELIMITER;
connect += ostrFileSize.str(); // the file size
connect += DELIMITER;
connect += buffer; // time sent
buffer = connect;

return true;
}

/*------------------------------------------------
    build packet for sending the actual data
--------------------------------------------------*/
bool Packet::package(string &buffer, int bufsize)
{

string temp;
string mainData;
ostringstream ostrSeq("");
ostringstream ostrBufSize("");

/* add sequence number */
seq++;

/* check if data is too much */
if (buffer.length() > MAXPACKET)
{
    protocol_message = "PACKET TOO BIG, QUITTING";
    return false;
}

if (bufsize == 0)
{
    protocol_message = "BUFFER SIZE IS ZERO, QUITTING";
    return false;
}
/* if the sequence gets to 10000 reset */
if (seq == 10000)
{
    seq = 0;
}
/* convert packet data size to string */
ostrSeq << seq;
ostrBufSize << buffer.length();

/* build the data header */
mainData += DATA; // header type
mainData += ostrSeq.str(); // sequence
mainData += DELIMITER;
mainData += ostrBufSize.str(); //amount of data being sent
mainData += DELIMITER;
mainData += buffer; // file name
//cout << mainData << "------------ data sent ---------- \n\n";
buffer = mainData;

return true;
}

/*------------------------------------------------
    build packet for the final terminating signal
--------------------------------------------------*/
bool Packet::package(string &buffer)
{

string mainData;
ostringstream ostrSeq("");
ostrSeq << seq;
/*
build the data header.
send and last qequence number
*/
mainData = TERMINATE + ostrSeq.str();

buffer = mainData;

return true;
}

#endif



Relevant Pages

  • Re: Cannot return values of char variable
    ... - buffer = ... Since you seem to be trying to return a char pointer ... int id = random; ... content is interpreted as a string. ...
    (comp.lang.c)
  • Re: How to split a compressed file programmatically?
    ... value is there in converting that to a string and then back to a long? ... And why allocate a new buffer for each chunk you want to write, ... void splitFile(string path, string path_parts, int size_part) ... just read chunks of the original file until you can't ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: How to split a compressed file programmatically?
    ... Personally, I would forget about the calculation altogether and just write a loop that keeps writing bytes in chunks as large as you want or however many bytes you have remaining, whichever is less, until you have no more bytes to write. ... The "size_part" variable is already a long; what possible value is there in converting that to a string and then back to a long? ... And why allocate a new buffer for each chunk you want to write, and why does that buffer have to be the length of the original file, and given that you're allocating a new buffer each time, why read the data anywhere other than the beginning of the buffer? ... void splitFile(string path, string path_parts, int size_part) ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: [RFC][PATCH] Escaping the arguments of kernel messages for sane user-space localisation
    ... escape certain characters in string arguments, ... We get rid of a 1K temporary buffer in printk. ... +static int printed_len; ... +static void printk_begin ...
    (Linux-Kernel)
  • Re: Writing an int to a file, not quite sure how buffers work.
    ... I still don't know how the buffer works. ... This will write the bit pattern of the int to the file. ... write the string "1234" to represent the integer 1234. ... integer-to string conversion routine, for instance to write in binary rather ...
    (comp.lang.c)