|
IBR-DTNSuite 0.6
|
00001 /* 00002 * dtnrecv.cpp 00003 * 00004 * Created on: 06.11.2009 00005 * Author: morgenro 00006 */ 00007 00008 #include "config.h" 00009 #include "ibrdtn/api/Client.h" 00010 #include "ibrdtn/api/FileBundle.h" 00011 #include "ibrcommon/net/tcpclient.h" 00012 #include "ibrcommon/thread/Mutex.h" 00013 #include "ibrcommon/thread/MutexLock.h" 00014 00015 #include <csignal> 00016 #include <sys/types.h> 00017 #include <iostream> 00018 00019 void print_help() 00020 { 00021 cout << "-- dtnrecv (IBR-DTN) --" << endl; 00022 cout << "Syntax: dtnrecv [options]" << endl; 00023 cout << "* optional parameters *" << endl; 00024 cout << " -h|--help display this text" << endl; 00025 cout << " --file <filename> write the incoming data to the a file instead of the standard output" << endl; 00026 cout << " --name <name> set the application name (e.g. filetransfer)" << endl; 00027 cout << " --timeout <seconds> receive timeout in seconds" << endl; 00028 cout << " --count <number> receive that many bundles" << endl; 00029 cout << " -U <socket> use UNIX domain sockets" << endl; 00030 } 00031 00032 dtn::api::Client *_client = NULL; 00033 ibrcommon::tcpclient *_conn = NULL; 00034 00035 int h = 0; 00036 bool _stdout = true; 00037 00038 void term(int signal) 00039 { 00040 if (!_stdout) 00041 { 00042 std::cout << h << " bundles received." << std::endl; 00043 } 00044 00045 if (signal >= 1) 00046 { 00047 if (_client != NULL) 00048 { 00049 _client->close(); 00050 _conn->close(); 00051 exit(0); 00052 } 00053 } 00054 } 00055 00056 int main(int argc, char *argv[]) 00057 { 00058 // catch process signals 00059 signal(SIGINT, term); 00060 signal(SIGTERM, term); 00061 00062 int ret = EXIT_SUCCESS; 00063 string filename = ""; 00064 string name = "filetransfer"; 00065 int timeout = 0; 00066 int count = 1; 00067 ibrcommon::File unixdomain; 00068 00069 for (int i = 0; i < argc; i++) 00070 { 00071 string arg = argv[i]; 00072 00073 // print help if requested 00074 if (arg == "-h" || arg == "--help") 00075 { 00076 print_help(); 00077 return ret; 00078 } 00079 00080 if (arg == "--name" && argc > i) 00081 { 00082 name = argv[i + 1]; 00083 } 00084 00085 if (arg == "--file" && argc > i) 00086 { 00087 filename = argv[i + 1]; 00088 _stdout = false; 00089 } 00090 00091 if (arg == "--timeout" && argc > i) 00092 { 00093 timeout = atoi(argv[i + 1]); 00094 } 00095 00096 if (arg == "--count" && argc > i) 00097 { 00098 count = atoi(argv[i + 1]); 00099 } 00100 00101 if (arg == "-U" && argc > i) 00102 { 00103 if (++i > argc) 00104 { 00105 std::cout << "argument missing!" << std::endl; 00106 return -1; 00107 } 00108 00109 unixdomain = ibrcommon::File(argv[i]); 00110 } 00111 } 00112 00113 try { 00114 // Create a stream to the server using TCP. 00115 ibrcommon::tcpclient conn; 00116 00117 // check if the unixdomain socket exists 00118 if (unixdomain.exists()) 00119 { 00120 // connect to the unix domain socket 00121 conn.open(unixdomain); 00122 } 00123 else 00124 { 00125 // connect to the standard local api port 00126 conn.open("127.0.0.1", 4550); 00127 00128 // enable nodelay option 00129 conn.enableNoDelay(); 00130 } 00131 00132 // Initiate a client for synchronous receiving 00133 dtn::api::Client client(name, conn); 00134 00135 // export objects for the signal handler 00136 _conn = &conn; 00137 _client = &client; 00138 00139 // Connect to the server. Actually, this function initiate the 00140 // stream protocol by starting the thread and sending the contact header. 00141 client.connect(); 00142 00143 std::fstream file; 00144 00145 if (!_stdout) 00146 { 00147 std::cout << "Wait for incoming bundle... " << std::endl; 00148 file.open(filename.c_str(), ios::in|ios::out|ios::binary|ios::trunc); 00149 file.exceptions(std::ios::badbit | std::ios::eofbit); 00150 } 00151 00152 for(h = 0; h < count; h++) 00153 { 00154 // receive the bundle 00155 dtn::api::Bundle b = client.getBundle(timeout); 00156 00157 // get the reference to the blob 00158 ibrcommon::BLOB::Reference ref = b.getData(); 00159 00160 // write the data to output 00161 if (_stdout) 00162 { 00163 cout << ref.iostream()->rdbuf(); 00164 } 00165 else 00166 { 00167 // write data to temporary file 00168 try { 00169 std::cout << "Bundle received (" << (h + 1) << ")." << endl; 00170 00171 file << ref.iostream()->rdbuf(); 00172 } catch (const ios_base::failure&) { 00173 00174 } 00175 } 00176 } 00177 00178 if (!_stdout) 00179 { 00180 file.close(); 00181 std::cout << "done." << std::endl; 00182 } 00183 00184 // Shutdown the client connection. 00185 client.close(); 00186 00187 // close the tcp connection 00188 conn.close(); 00189 } catch (const dtn::api::ConnectionTimeoutException&) { 00190 std::cerr << "Timeout." << std::endl; 00191 ret = EXIT_FAILURE; 00192 } catch (const dtn::api::ConnectionAbortedException&) { 00193 std::cerr << "Aborted." << std::endl; 00194 ret = EXIT_FAILURE; 00195 } catch (const dtn::api::ConnectionException&) { 00196 } catch (const std::exception &ex) { 00197 std::cerr << "Error: " << ex.what() << std::endl; 00198 ret = EXIT_FAILURE; 00199 } 00200 00201 return ret; 00202 }