OK, in the docs, it is stated that tcpstream behaves similar to an fstream. I need a method that will read from a client until it reaches a blank line, and then writes. I have gone round and round in circles on this one. I have noted that this little piece of code seems to work with fstream and a text file that contains a mock http header from a client, a blank line and then meaningless data after the blank line.
#include <fstream>
#include <cstdlib>
using namespace std;
int main(int argc, char ** argv)
{
for (int i = 0; i < argc; i++)
{
char line[100];
ifstream file(argv[i]);
This little piece, however, does not work with tcpstream. Is there a public method that will tell tcpstream to stop reading when it reaches a blank line and start transmitting? I am just learning C++, or I would write this method myself.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
What output lines line per line do you actually get back if you read output from the http server with tcpstream and echo each line to the console? Also, at least some ASCII protocols do commonly use \r\n pairs rather than pure \n's though I dont know offhand if this is common with http...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
> Also, at least some ASCII protocols do
> commonly use \r\n pairs rather than pure \n's
> though I dont know offhand if this is common
> with http...
OK, I feel stupid. Yes, \r\n is the standard for http communication.
This
if ( strcmp(line,"\r") == 0 )
works!
getline() strips the '\n'
Thanks for your help!
BTW, would the CommonC++ project be interested in an httpstream subclass that will parse client headers, return vars like httpstream.getUserAgent()? I suppose something like this should be threaded (or forked?). It would be a worthy excercise for me, and others may benefit from it.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK, here is a new problem. This has to do with tcpstream's odd behaviour with manipulating strings. I have written a piece of code that collects the http header from the client and attempts to create a sort of associative array (perl talk) out of it. Here it is:
.
.
.
map<string,string,less<string> > var;
.
.
.
while ( tcp.getline(line,100,'\n') )
{
if ( strcmp(line,"\r") == 0 )
{
break;
}
else
{
// define our delimiter
char del = ':';
// create a string object from the line that was read.
string sline(line);
// find the position of our delimiter
int pos1 = sline.find_first_of(del);
// Get the size of our string object minus the \r
int size = sline.size() - 1;
// position 2 is 2xchar past the position of our delimiter
// this eliminates the actual ':' char and the empty space that folows
int pos2 = pos1 + 2;
// assign a new string from the beginning to our delimiter
string varname = sline.substr(0,pos1);
// asign a new string from position 2 to the end.
// This compiles OK, but tcpstream dies (exits normally)
// after we do this. Why?
string value = sline.substr(pos2,size);
var[varname] = value;
cout << line << endl;
}
}
This is what I get in the backtrace:
#0 0x400c2a71 in __kill () from /lib/libc.so.6
#1 0x4001d36a in pthread_kill () at signals.c:220
#2 0x4001d826 in raise () at signals.c:166
#3 0x400c3e0f in abort () at ../sysdeps/generic/abort.c:139
#4 0x40063a28 in __default_terminate () from /usr/lib/libstdc++-libc6.1-2.so.3
#5 0x40063a4d in __terminate () from /usr/lib/libstdc++-libc6.1-2.so.3
#6 0x400644e6 in throw_helper (eh=0x8052d90, pc=0x400bca5d,
my_udata=0xbffff19c, offset_p=0xbffff198)
from /usr/lib/libstdc++-libc6.1-2.so.3
#7 0x400646b5 in __throw () from /usr/lib/libstdc++-libc6.1-2.so.3
#8 0x804be95 in main (argc=1, argv=0xbffff5f4) at main.cpp:131
line 131 in main.cpp contains the close bracket for :
try
{
Servlet server(addr, port);
Any ideas?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I really should take a deep breath before posting here. I figured it out, my deepest apologies to anyone who might have been trying to figure out what I was doing wrong.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK, in the docs, it is stated that tcpstream behaves similar to an fstream. I need a method that will read from a client until it reaches a blank line, and then writes. I have gone round and round in circles on this one. I have noted that this little piece of code seems to work with fstream and a text file that contains a mock http header from a client, a blank line and then meaningless data after the blank line.
#include <fstream>
#include <cstdlib>
using namespace std;
int main(int argc, char ** argv)
{
for (int i = 0; i < argc; i++)
{
char line[100];
ifstream file(argv[i]);
while ( file.getline(line,100,'\n') )
{
if ( strcmp(line,"") == 0 )
{
cout << "Blank Line" << endl;
break;
}
else
{
cout << line << endl;
}
}
}
}
This little piece, however, does not work with tcpstream. Is there a public method that will tell tcpstream to stop reading when it reaches a blank line and start transmitting? I am just learning C++, or I would write this method myself.
What output lines line per line do you actually get back if you read output from the http server with tcpstream and echo each line to the console? Also, at least some ASCII protocols do commonly use \r\n pairs rather than pure \n's though I dont know offhand if this is common with http...
> Also, at least some ASCII protocols do
> commonly use \r\n pairs rather than pure \n's
> though I dont know offhand if this is common
> with http...
OK, I feel stupid. Yes, \r\n is the standard for http communication.
This
if ( strcmp(line,"\r") == 0 )
works!
getline() strips the '\n'
Thanks for your help!
BTW, would the CommonC++ project be interested in an httpstream subclass that will parse client headers, return vars like httpstream.getUserAgent()? I suppose something like this should be threaded (or forked?). It would be a worthy excercise for me, and others may benefit from it.
OK, here is a new problem. This has to do with tcpstream's odd behaviour with manipulating strings. I have written a piece of code that collects the http header from the client and attempts to create a sort of associative array (perl talk) out of it. Here it is:
.
.
.
map<string,string,less<string> > var;
.
.
.
while ( tcp.getline(line,100,'\n') )
{
if ( strcmp(line,"\r") == 0 )
{
break;
}
else
{
// define our delimiter
char del = ':';
// create a string object from the line that was read.
string sline(line);
// find the position of our delimiter
int pos1 = sline.find_first_of(del);
// Get the size of our string object minus the \r
int size = sline.size() - 1;
// position 2 is 2xchar past the position of our delimiter
// this eliminates the actual ':' char and the empty space that folows
int pos2 = pos1 + 2;
// assign a new string from the beginning to our delimiter
string varname = sline.substr(0,pos1);
// asign a new string from position 2 to the end.
// This compiles OK, but tcpstream dies (exits normally)
// after we do this. Why?
string value = sline.substr(pos2,size);
var[varname] = value;
cout << line << endl;
}
}
This is what I get in the backtrace:
#0 0x400c2a71 in __kill () from /lib/libc.so.6
#1 0x4001d36a in pthread_kill () at signals.c:220
#2 0x4001d826 in raise () at signals.c:166
#3 0x400c3e0f in abort () at ../sysdeps/generic/abort.c:139
#4 0x40063a28 in __default_terminate () from /usr/lib/libstdc++-libc6.1-2.so.3
#5 0x40063a4d in __terminate () from /usr/lib/libstdc++-libc6.1-2.so.3
#6 0x400644e6 in throw_helper (eh=0x8052d90, pc=0x400bca5d,
my_udata=0xbffff19c, offset_p=0xbffff198)
from /usr/lib/libstdc++-libc6.1-2.so.3
#7 0x400646b5 in __throw () from /usr/lib/libstdc++-libc6.1-2.so.3
#8 0x804be95 in main (argc=1, argv=0xbffff5f4) at main.cpp:131
line 131 in main.cpp contains the close bracket for :
try
{
Servlet server(addr, port);
Any ideas?
I really should take a deep breath before posting here. I figured it out, my deepest apologies to anyone who might have been trying to figure out what I was doing wrong.