From 37a8bfebc9b90a67ef9acb88ecfac270d072aaad Mon Sep 17 00:00:00 2001 From: Davis King Date: Sat, 17 Nov 2012 14:48:42 -0500 Subject: [PATCH] Added an example for the iosockstream and server_iostream objects. Also reorganized the sockets example programs a little. --HG-- rename : examples/sockstreambuf_ex.cpp => examples/server_iostream_ex.cpp rename : examples/sockets_ex_2.cpp => examples/sockstreambuf_ex.cpp --- examples/CMakeLists.txt | 3 +- examples/iosockstream_ex.cpp | 47 ++++++++++++ examples/server_iostream_ex.cpp | 86 ++++++++++++++++++++++ examples/sockets_ex_2.cpp | 88 ----------------------- examples/sockstreambuf_ex.cpp | 124 ++++++++++++++++---------------- 5 files changed, 197 insertions(+), 151 deletions(-) create mode 100644 examples/iosockstream_ex.cpp create mode 100644 examples/server_iostream_ex.cpp delete mode 100644 examples/sockets_ex_2.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 05c957df4..94dcf285e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -50,6 +50,7 @@ add_example(file_to_code_ex) add_example(graph_labeling_ex) add_example(gui_api_ex) add_example(image_ex) +add_example(iosockstream_ex) add_example(kcentroid_ex) add_example(kkmeans_ex) add_example(krls_ex) @@ -79,8 +80,8 @@ add_example(rvm_ex) add_example(rvm_regression_ex) add_example(sequence_labeler_ex) add_example(server_http_ex) +add_example(server_iostream_ex) add_example(sockets_ex) -add_example(sockets_ex_2) add_example(sockstreambuf_ex) add_example(std_allocator_ex) add_example(surf_ex) diff --git a/examples/iosockstream_ex.cpp b/examples/iosockstream_ex.cpp new file mode 100644 index 000000000..745e56fed --- /dev/null +++ b/examples/iosockstream_ex.cpp @@ -0,0 +1,47 @@ +// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt +/* + + This is an example illustrating the use of the iosockstream object from the + dlib C++ Library. + + This program simply connects to www.google.com at port 80 and requests the + main Google web page. It then prints what it gets back from Google to the + screen. + + + For those of you curious about HTTP check out the excellent introduction at + http://www.jmarshall.com/easy/http/ +*/ + +#include "dlib/iosockstream.h" +#include + +using namespace std; +using namespace dlib; + +int main() +{ + try + { + // Connect to Google's web server which listens on port 80. If this + // fails it will throw a dlib::socket_error exception. + iosockstream stream("www.google.com:80"); + + // At this point, we can use stream the same way we would use any other + // C++ iostream object. So to test it out, lets make a HTTP GET request + // for the main Google page. + stream << "GET / HTTP/1.0\r\n\r\n"; + + // Here we print each character we get back one at a time. + while (stream.peek() != EOF) + { + ch = (char)stream.get(); + } + } + catch (exception& e) + { + cout << e.what() << endl; + } +} + + diff --git a/examples/server_iostream_ex.cpp b/examples/server_iostream_ex.cpp new file mode 100644 index 000000000..402b4c622 --- /dev/null +++ b/examples/server_iostream_ex.cpp @@ -0,0 +1,86 @@ +// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt +/* + + This is an example illustrating the use of the server_iostream object from + the dlib C++ Library. + + This is a simple echo server. It listens on port 1234 for incoming + connections and just echos back any text it receives, but in upper case. So + basically it is the same as the sockets_ex.cpp example program except it + uses iostreams. + + To test it out you can just open a command prompt and type: + telnet localhost 1234 + + Then you can type away. + +*/ + + + + +#include "dlib/sockets.h" +#include "dlib/server.h" +#include "dlib/sockstreambuf.h" +#include + +using namespace dlib; +using namespace std; + + + +class serv : public server_iostream +{ + + void on_connect ( + std::istream& in, + std::ostream& out, + const std::string& foreign_ip, + const std::string& local_ip, + unsigned short foreign_port, + unsigned short local_port, + uint64 connection_id + ) + { + // The details of the connection are contained in the last few arguments to + // on_connect(). For more information, see the documentation for the + // server_iostream. However, the main arguments of interest are the two streams. + // Here we also print the IP address of the remote machine. + cout << "Got a connection from " << foreign_ip << endl; + + // Loop until we hit the end of the stream. This happens when the connection + // terminates. + while (in.peek() != EOF) + { + // get the next character from the client + char ch = in.get(); + + // now echo it back to them + out << toupper(ch); + } + } + +}; + + +int main() +{ + try + { + serv our_server; + + // set up the server object we have made + our_server.set_listening_port(1234); + // Tell the server to begin accepting connections. + our_server.start_async(); + + cout << "Press enter to end this program" << endl; + cin.get(); + } + catch (exception& e) + { + cout << e.what() << endl; + } +} + + diff --git a/examples/sockets_ex_2.cpp b/examples/sockets_ex_2.cpp deleted file mode 100644 index 8abd52bfd..000000000 --- a/examples/sockets_ex_2.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt -/* - - This is an example illustrating the use of the sockets and - sockstreambuf components from the dlib C++ Library. - - This program simply connects to www.google.com at port 80 and requests the - main Google web page. It then prints what it gets back from Google to the - screen. - - - For those of you curious about HTTP check out the excellent introduction at - http://www.jmarshall.com/easy/http/ -*/ - -#include "dlib/sockets.h" -#include "dlib/sockstreambuf.h" -#include - -using namespace std; -using namespace dlib; - -int main() -{ - try - { - // Connect to Google's web server which listens on port 80. If this - // fails it will throw a dlib::socket_error exception. Note that we - // are using a smart pointer here to contain the connection pointer - // returned from connect. Doing this ensures that the connection - // is deleted even if someone throws an exception somewhere in your code. - scoped_ptr con(connect("www.google.com",80)); - - - { - // Create a stream buffer for our connection - sockstreambuf buf(con); - // Now stick that stream buffer into an iostream object - iostream stream(&buf); - // This command causes the iostream to flush its output buffers - // whenever someone makes a read request. - stream.tie(&stream); - - // Now we make the HTTP GET request for the main Google page. - stream << "GET / HTTP/1.0\r\n\r\n"; - - // Here we print each character we get back one at a time. - int ch = stream.get(); - while (ch != EOF) - { - cout << (char)ch; - ch = stream.get(); - } - - // At the end of this scope buf will be destructed and flush - // anything it still contains to the connection. Thus putting - // this } here makes it safe to destroy the connection later on. - // If we just destroyed the connection before buf was destructed - // then buf might try to flush its data to a closed connection - // which would be an error. - } - - // Here we call close_gracefully(). It takes a connection and performs - // a proper TCP shutdown by sending a FIN packet to the other end of the - // connection and waiting half a second for the other end to close the - // connection as well. If half a second goes by without the other end - // responding then the connection is forcefully shutdown and deleted. - // - // You usually want to perform a graceful shutdown of your TCP connections - // because there might be some data you tried to send that is still buffered - // in the operating system's output buffers. If you just killed the - // connection it might not be sent to the other side (although maybe - // you don't care, and in the case of this example it doesn't really matter. - // But I'm only putting this here for the purpose of illustration :-). - // In any case, this function is provided to allow you to perform a graceful - // close if you so choose. - // - // Also note that the timeout can be changed by suppling an optional argument - // to this function. - close_gracefully(con); - } - catch (exception& e) - { - cout << e.what() << endl; - } -} - - diff --git a/examples/sockstreambuf_ex.cpp b/examples/sockstreambuf_ex.cpp index e60cddcff..87b1f8c46 100644 --- a/examples/sockstreambuf_ex.cpp +++ b/examples/sockstreambuf_ex.cpp @@ -1,85 +1,85 @@ // The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt /* - This is an example illustrating the use of the sockets, - server and sockstreambuf components from the dlib C++ Library. + This is an example illustrating the use of the sockets and sockstreambuf + components from the dlib C++ Library. Note that there is also an + iosockstream object in dlib that is often simpler to use, see + iosockstream_ex.cpp for an example of its use. - This is a simple echo server. It listens on port 1234 for incoming - connections and just echos back any text it receives but in upper case. - So basically it is the same as the other sockets example except it - uses stream buffers. - - To test it out you can just open a command prompt and type: - telnet localhost 1234 - - Then you can type away. + This program simply connects to www.google.com at port 80 and requests the + main Google web page. It then prints what it gets back from Google to the + screen. - Also note that a good reference on the standard C++ iostream library can be - found at http://www.cplusplus.com/ref/iostream/ + For those of you curious about HTTP check out the excellent introduction at + http://www.jmarshall.com/easy/http/ */ - - - #include "dlib/sockets.h" -#include "dlib/server.h" #include "dlib/sockstreambuf.h" #include -using namespace dlib; using namespace std; - - - -class serv : public server -{ - - void on_connect ( - connection& con - ) - { - // create a sockstreambuf that reads/writes on our connection. - sockstreambuf buf(&con); - - // Now we make an iostream object that reads/writes to our streambuffer. A lot of people - // don't seem to know that the C++ iostreams are as powerful as they are. So what I'm doing - // here isn't anything special and is totally portable. You will be able to use this stream - // object just as you would any iostream from the standard library. - iostream stream(&buf); - - // This command causes our stream to flush its output buffers whenever you ask it for more - // data. - stream.tie(&stream); - - char ch; - // Loop until we hit the end of the stream. This happens when the connection terminates. - while (stream.peek() != EOF) - { - // get the next character from the client - ch = stream.get(); - - // now echo it back to them - stream << (char)toupper(ch); - } - } - -}; - +using namespace dlib; int main() { try { - serv our_server; + // Connect to Google's web server which listens on port 80. If this + // fails it will throw a dlib::socket_error exception. Note that we + // are using a smart pointer here to contain the connection pointer + // returned from connect. Doing this ensures that the connection + // is deleted even if someone throws an exception somewhere in your code. + scoped_ptr con(connect("www.google.com",80)); - // set up the server object we have made - our_server.set_listening_port(1234); - // Tell the server to begin accepting connections. - our_server.start_async(); - cout << "Press enter to end this program" << endl; - cin.get(); + { + // Create a stream buffer for our connection + sockstreambuf buf(con); + // Now stick that stream buffer into an iostream object + iostream stream(&buf); + // This command causes the iostream to flush its output buffers + // whenever someone makes a read request. + stream.tie(&stream); + + // Now we make the HTTP GET request for the main Google page. + stream << "GET / HTTP/1.0\r\n\r\n"; + + // Here we print each character we get back one at a time. + int ch = stream.get(); + while (ch != EOF) + { + cout << (char)ch; + ch = stream.get(); + } + + // At the end of this scope buf will be destructed and flush + // anything it still contains to the connection. Thus putting + // this } here makes it safe to destroy the connection later on. + // If we just destroyed the connection before buf was destructed + // then buf might try to flush its data to a closed connection + // which would be an error. + } + + // Here we call close_gracefully(). It takes a connection and performs + // a proper TCP shutdown by sending a FIN packet to the other end of the + // connection and waiting half a second for the other end to close the + // connection as well. If half a second goes by without the other end + // responding then the connection is forcefully shutdown and deleted. + // + // You usually want to perform a graceful shutdown of your TCP connections + // because there might be some data you tried to send that is still buffered + // in the operating system's output buffers. If you just killed the + // connection it might not be sent to the other side (although maybe + // you don't care, and in the case of this example it doesn't really matter. + // But I'm only putting this here for the purpose of illustration :-). + // In any case, this function is provided to allow you to perform a graceful + // close if you so choose. + // + // Also note that the timeout can be changed by suppling an optional argument + // to this function. + close_gracefully(con); } catch (exception& e) {