本文整理汇总了C++中socket::Connection::connected方法的典型用法代码示例。如果您正苦于以下问题:C++ Connection::connected方法的具体用法?C++ Connection::connected怎么用?C++ Connection::connected使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类socket::Connection
的用法示例。
在下文中一共展示了Connection::connected方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: main
int main(int argc, char ** argv){
Util::Config conf(argv[0], PACKAGE_VERSION);
conf.addConnectorOptions(1935);
conf.parseArgs(argc, argv);
Socket::Server server_socket = Socket::Server("/tmp/mist/http_smooth");
if ( !server_socket.connected()){
return 1;
}
conf.activate();
while (server_socket.connected() && conf.is_active){
Socket::Connection S = server_socket.accept();
if (S.connected()){ //check if the new connection is valid
pid_t myid = fork();
if (myid == 0){ //if new child, start MAINHANDLER
return Connector_HTTP::Connector_HTTP_Dynamic(S);
}else{ //otherwise, do nothing or output debugging text
#if DEBUG >= 3
fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket());
#endif
}
}
} //while connected
server_socket.close();
return 0;
} //main
示例2: main
int main(int argc, char ** argv){
Util::Config conf(argv[0], PACKAGE_VERSION);
conf.addOption("streamname",
JSON::fromString("{\"arg\":\"string\",\"arg_num\":1,\"help\":\"The name of the stream that this connector will transmit.\"}"));
conf.addConnectorOptions(8888);
conf.parseArgs(argc, argv);
Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface"));
if ( !server_socket.connected()){
return 1;
}
conf.activate();
while (server_socket.connected() && conf.is_active){
Socket::Connection S = server_socket.accept();
if (S.connected()){ //check if the new connection is valid
pid_t myid = fork();
if (myid == 0){ //if new child, start MAINHANDLER
return Connector_TS::tsConnector(S, conf.getString("streamname"));
}else{ //otherwise, do nothing or output debugging text
#if DEBUG >= 5
fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket());
#endif
}
}
} //while connected
server_socket.close();
return 0;
} //main
示例3: while
/// Blocks until either the stream encounters a pause mark or the sourceSocket errors.
/// This function is intended to be run after the 'q' command is sent, throwing away superfluous packets.
/// It will time out after 5 seconds, disconnecting the sourceSocket.
void DTSC::Stream::waitForPause(Socket::Connection & sourceSocket) {
bool wasBlocking = sourceSocket.isBlocking();
sourceSocket.setBlocking(false);
//cancel the attempt after 5000 milliseconds
long long int start = Util::getMS();
while (lastType() != DTSC::PAUSEMARK && sourceSocket.connected() && Util::getMS() - start < 5000) {
//we have data? parse it
if (sourceSocket.Received().size()) {
//return value is ignored because we're not interested.
parsePacket(sourceSocket.Received());
}
//still no pause mark? check for more data
if (lastType() != DTSC::PAUSEMARK) {
if (sourceSocket.spool()) {
//more received? attempt to read
//return value is ignored because we're not interested in data packets, just metadata.
parsePacket(sourceSocket.Received());
} else {
//nothing extra to receive? wait a bit and retry
Util::sleep(10);
}
}
}
sourceSocket.setBlocking(wasBlocking);
//if the timeout has passed, close the socket
if (Util::getMS() - start >= 5000) {
sourceSocket.close();
//and optionally print a debug message that this happened
DEBUG_MSG(DLVL_DEVEL, "Timing out while waiting for pause break");
}
}
示例4: handleStats
void handleStats(void * empty){
if (empty != 0){return;}
std::string double_newline = "\n\n";
Socket::Connection StatsSocket = Socket::Connection("/tmp/mist/statistics", true);
while (buffer_running){
usleep(1000000); //sleep one second
if (!StatsSocket.connected()){
StatsSocket = Socket::Connection("/tmp/mist/statistics", true);
}
if (StatsSocket.connected()){
StatsSocket.Send(Stream::get()->getStats());
StatsSocket.Send(double_newline);
StatsSocket.flush();
}
}
StatsSocket.close();
}
示例5: Start
/// Starts a loop, waiting for connections to send data to.
int Start(int argc, char ** argv) {
Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION);
conf.addOption("stream_name", JSON::fromString("{\"arg_num\":1, \"arg\":\"string\", \"help\":\"Name of the stream this buffer will be providing.\"}"));
conf.addOption("awaiting_ip", JSON::fromString("{\"arg_num\":2, \"arg\":\"string\", \"default\":\"\", \"help\":\"IP address to expect incoming data from. This will completely disable reading from standard input if used.\"}"));
conf.addOption("reportstats", JSON::fromString("{\"default\":0, \"help\":\"Report stats to a controller process.\", \"short\":\"s\", \"long\":\"reportstats\"}"));
conf.parseArgs(argc, argv);
std::string name = conf.getString("stream_name");
SS = Util::Stream::makeLive(name);
if (!SS.connected()) {
perror("Could not create stream socket");
return 1;
}
conf.activate();
thisStream = Stream::get();
thisStream->setName(name);
Socket::Connection incoming;
Socket::Connection std_input(fileno(stdin));
tthread::thread * StatsThread = 0;
if (conf.getBool("reportstats")){StatsThread = new tthread::thread(handleStats, 0);}
tthread::thread * StdinThread = 0;
std::string await_ip = conf.getString("awaiting_ip");
if (await_ip == ""){
StdinThread = new tthread::thread(handleStdin, 0);
}else{
thisStream->setWaitingIP(await_ip);
StdinThread = new tthread::thread(handlePushin, 0);
}
while (buffer_running && SS.connected() && conf.is_active){
//check for new connections, accept them if there are any
//starts a thread for every accepted connection
incoming = SS.accept(true);
if (incoming.connected()){
user * usr_ptr = new user(incoming);
thisStream->addUser(usr_ptr);
usr_ptr->Thread = new tthread::thread(handleUser, (void *)usr_ptr);
}
}//main loop
// disconnect listener
buffer_running = false;
std::cout << "End of input file - buffer shutting down" << std::endl;
SS.close();
if (StatsThread){StatsThread->join();}
StdinThread->join();
delete thisStream;
return 0;
}
示例6: main
int main(int argc, char ** argv){
Util::Config conf(argv[0], PACKAGE_VERSION);
JSON::Value capa;
capa["desc"] = "Enables the raw MPEG Transport Stream protocol over TCP.";
capa["deps"] = "";
capa["required"]["streamname"]["name"] = "Stream";
capa["required"]["streamname"]["help"] = "What streamname to serve. For multiple streams, add this protocol multiple times using different ports.";
capa["required"]["streamname"]["type"] = "str";
capa["required"]["streamname"]["option"] = "--stream";
capa["optional"]["tracks"]["name"] = "Tracks";
capa["optional"]["tracks"]["help"] = "The track IDs of the stream that this connector will transmit separated by spaces";
capa["optional"]["tracks"]["type"] = "str";
capa["optional"]["tracks"]["option"] = "--tracks";
conf.addOption("streamname",
JSON::fromString("{\"arg\":\"string\",\"short\":\"s\",\"long\":\"stream\",\"help\":\"The name of the stream that this connector will transmit.\"}"));
conf.addOption("tracks",
JSON::fromString("{\"arg\":\"string\",\"value\":[\"\"],\"short\": \"t\",\"long\":\"tracks\",\"help\":\"The track IDs of the stream that this connector will transmit separated by spaces.\"}"));
conf.addConnectorOptions(8888, capa);
bool ret = conf.parseArgs(argc, argv);
if (conf.getBool("json")){
std::cout << capa.toString() << std::endl;
return -1;
}
if (!ret){
std::cerr << "Usage error: missing argument(s)." << std::endl;
conf.printHelp(std::cout);
return 1;
}
Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface"));
if ( !server_socket.connected()){
return 1;
}
conf.activate();
while (server_socket.connected() && conf.is_active){
Socket::Connection S = server_socket.accept();
if (S.connected()){ //check if the new connection is valid
pid_t myid = fork();
if (myid == 0){ //if new child, start MAINHANDLER
return Connector_TS::tsConnector(S, conf.getString("streamname"), conf.getString("tracks"));
}else{ //otherwise, do nothing or output debugging text
#if DEBUG >= 5
fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket());
#endif
}
}
} //while connected
server_socket.close();
return 0;
} //main
示例7: main
///\brief Contains the main code for the RAW connector.
///
///Expects a single commandline argument telling it which stream to connect to,
///then outputs the raw stream to stdout.
int main(int argc, char ** argv){
Util::Config conf(argv[0], PACKAGE_VERSION);
JSON::Value capa;
conf.addBasicConnectorOptions(capa);
conf.addOption("stream_name", JSON::fromString("{\"arg_num\":1, \"help\":\"Name of the stream to write to stdout.\"}"));
conf.parseArgs(argc, argv);
if (conf.getBool("json")){
std::cout << "null" << std::endl;
return -1;
}
//connect to the proper stream
Socket::Connection S = Util::Stream::getStream(conf.getString("stream_name"));
S.setBlocking(false);
if ( !S.connected()){
std::cout << "Could not open stream " << conf.getString("stream_name") << std::endl;
return 1;
}
long long int lastStats = 0;
long long int started = Util::epoch();
while (std::cout.good()){
if (S.spool()){
while (S.Received().size()){
std::cout.write(S.Received().get().c_str(), S.Received().get().size());
S.Received().get().clear();
}
}else{
Util::sleep(10); //sleep 10ms if no data
}
unsigned int now = Util::epoch();
if (now != lastStats){
lastStats = now;
std::stringstream st;
st << "S localhost RAW " << (Util::epoch() - started) << " " << S.dataDown() << " " << S.dataUp() << "\n";
S.SendNow(st.str().c_str());
}
}
std::stringstream st;
st << "S localhost RAW " << (Util::epoch() - started) << " " << S.dataDown() << " " << S.dataUp() << "\n";
S.SendNow(st.str().c_str());
S.close();
return 0;
}
示例8: main
///\brief The standard process-spawning main function.
int main(int argc, char ** argv){
Util::Config conf(argv[0], PACKAGE_VERSION);
JSON::Value capa;
capa["desc"] = "Enables the RTMP protocol which is used by Adobe Flash Player.";
capa["deps"] = "";
capa["url_rel"] = "/play/$";
capa["codecs"][0u][0u].append("H264");
capa["codecs"][0u][0u].append("H263");
capa["codecs"][0u][0u].append("VP6");
capa["codecs"][0u][1u].append("AAC");
capa["codecs"][0u][1u].append("MP3");
capa["methods"][0u]["handler"] = "rtmp";
capa["methods"][0u]["type"] = "flash/10";
capa["methods"][0u]["priority"] = 6ll;
conf.addConnectorOptions(1935, capa);
conf.parseArgs(argc, argv);
if (conf.getBool("json")){
std::cout << capa.toString() << std::endl;
return -1;
}
Socket::Server server_socket = Socket::Server(conf.getInteger("listen_port"), conf.getString("listen_interface"));
if ( !server_socket.connected()){
return 1;
}
conf.activate();
while (server_socket.connected() && conf.is_active){
Socket::Connection S = server_socket.accept();
if (S.connected()){ //check if the new connection is valid
pid_t myid = fork();
if (myid == 0){ //if new child, start MAINHANDLER
return Connector_RTMP::rtmpConnector(S);
}else{ //otherwise, do nothing or output debugging text
#if DEBUG >= 5
fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket());
#endif
}
}
} //while connected
server_socket.close();
return 0;
} //main
示例9: Connector_HTTP_Dynamic
/// Main function for Connector_HTTP_Dynamic
int Connector_HTTP_Dynamic(Socket::Connection conn){
std::deque<std::string> FlashBuf;
std::vector<int> Timestamps;
int FlashBufSize = 0;
long long int FlashBufTime = 0;
DTSC::Stream Strm; //Incoming stream buffer.
HTTP::Parser HTTP_R, HTTP_S; //HTTP Receiver en HTTP Sender.
bool ready4data = false; //Set to true when streaming is to begin.
bool pending_manifest = false;
bool receive_marks = false; //when set to true, this stream will ignore keyframes and instead use pause marks
bool inited = false;
Socket::Connection ss( -1);
std::string streamname;
std::string recBuffer = "";
bool wantsVideo = false;
bool wantsAudio = false;
std::string Quality;
int Segment = -1;
long long int ReqFragment = -1;
int temp;
std::string tempStr;
int Flash_RequestPending = 0;
unsigned int lastStats = 0;
conn.setBlocking(false); //do not block on conn.spool() when no data is available
while (conn.connected()){
if (conn.spool() || conn.Received().size()){
//make sure it ends in a \n
if ( *(conn.Received().get().rbegin()) != '\n'){
std::string tmp = conn.Received().get();
conn.Received().get().clear();
if (conn.Received().size()){
conn.Received().get().insert(0, tmp);
}else{
conn.Received().append(tmp);
}
}
if (HTTP_R.Read(conn.Received().get())){
#if DEBUG >= 4
std::cout << "Received request: " << HTTP_R.getUrl() << std::endl;
#endif
conn.setHost(HTTP_R.GetHeader("X-Origin"));
if (HTTP_R.url.find("Manifest") == std::string::npos){
streamname = HTTP_R.url.substr(8, HTTP_R.url.find("/", 8) - 12);
if ( !ss){
ss = Util::Stream::getStream(streamname);
if ( !ss.connected()){
#if DEBUG >= 1
fprintf(stderr, "Could not connect to server!\n");
#endif
ss.close();
HTTP_S.Clean();
HTTP_S.SetBody("No such stream " + streamname + " is available on the system. Please try again.\n");
conn.SendNow(HTTP_S.BuildResponse("404", "Not found"));
ready4data = false;
continue;
}
ss.setBlocking(false);
inited = true;
}
Quality = HTTP_R.url.substr(HTTP_R.url.find("/Q(", 8) + 3);
Quality = Quality.substr(0, Quality.find(")"));
tempStr = HTTP_R.url.substr(HTTP_R.url.find(")/") + 2);
wantsAudio = false;
wantsVideo = false;
if (tempStr[0] == 'A'){
wantsAudio = true;
}
if (tempStr[0] == 'V'){
wantsVideo = true;
}
tempStr = tempStr.substr(tempStr.find("(") + 1);
ReqFragment = atoll(tempStr.substr(0, tempStr.find(")")).c_str());
#if DEBUG >= 4
printf("Quality: %s, Frag %d\n", Quality.c_str(), (ReqFragment / 10000));
#endif
std::stringstream sstream;
sstream << "s " << (ReqFragment / 10000) << "\no \n";
ss.SendNow(sstream.str().c_str());
Flash_RequestPending++;
}else{
streamname = HTTP_R.url.substr(8, HTTP_R.url.find("/", 8) - 12);
if ( !Strm.metadata.isNull()){
HTTP_S.Clean();
HTTP_S.SetHeader("Content-Type", "text/xml");
HTTP_S.SetHeader("Cache-Control", "no-cache");
if (Strm.metadata.isMember("length")){
receive_marks = true;
}
std::string manifest = BuildManifest(streamname, Strm.metadata);
HTTP_S.SetBody(manifest);
conn.SendNow(HTTP_S.BuildResponse("200", "OK"));
#if DEBUG >= 3
printf("Sent manifest\n");
#endif
//.........这里部分代码省略.........
示例10: Start
///\brief Starts a loop, waiting for connections to send data to.
///\param argc The number of arguments to the program.
///\param argv The arguments to the program.
///\return The return code of the buffer.
int Start(int argc, char ** argv){
/*std::ofstream myfile ("/home/sharvanath/mistserver/test.txt",std::ios::app);
//struct sockaddr add;
//socklen_t add_length=sizeof(struct sockaddr);
//getsockname(incoming.sock, &add,&add_length);
myfile<<"hello1\n";
//myfile << "the family here is : "<<add.sa_family<<"\n";
myfile.close();
*/
Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION);
conf.addOption("stream_name",
JSON::fromString("{\"arg_num\":1, \"arg\":\"string\", \"help\":\"Name of the stream this buffer will be providing.\"}"));
conf.addOption("awaiting_ip",
JSON::fromString(
"{\"arg_num\":2, \"arg\":\"string\", \"default\":\"\", \"help\":\"IP address to expect incoming data from. This will completely disable reading from standard input if used.\"}"));
conf.addOption("reportstats",
JSON::fromString("{\"default\":0, \"help\":\"Report stats to a controller process.\", \"short\":\"s\", \"long\":\"reportstats\"}"));
conf.addOption("time",
JSON::fromString(
"{\"default\":0, \"arg\": \"integer\", \"help\":\"Buffer a specied amount of time in ms.\", \"short\":\"t\", \"long\":\"time\"}"));
conf.parseArgs(argc, argv);
std::string name = conf.getString("stream_name");
SS = Util::Stream::makeLive(name);
if ( !SS.connected()){
perror("Could not create stream socket");
return 1;
}
SS.setBlocking(false);
conf.activate();
thisStream = Stream::get();
thisStream->setName(name);
thisStream->getStream()->setBufferTime(conf.getInteger("time"));
Socket::Connection incoming;
Socket::Connection std_input(fileno(stdin));
if (conf.getBool("reportstats")){
tthread::thread StatsThread(handleStats, 0);
StatsThread.detach();
}
std::string await_ip = conf.getString("awaiting_ip");
if (await_ip == ""){
tthread::thread StdinThread(handleStdin, 0);
StdinThread.detach();
}else{
thisStream->setWaitingIP(await_ip);
tthread::thread StdinThread(handlePushin, 0);
StdinThread.detach();
}
while (buffer_running && SS.connected() && conf.is_active){
//check for new connections, accept them if there are any
//starts a thread for every accepted connection
//sharva_mod
incoming = SS.accept(true);
if (incoming.connected()){
tthread::thread thisUser(handleUser, (void *)new user(incoming));
thisUser.detach();
}else{
Util::sleep(50);//sleep 50ms
}
} //main loop
// disconnect listener
buffer_running = false;
std::cout << "Buffer shutting down" << std::endl;
SS.close();
if (thisStream->getIPInput().connected()){
thisStream->getIPInput().close();
}
delete thisStream;
return 0;
}
示例11: dynamicConnector
///\brief Main function for the HTTP Dynamic Connector
///\param conn A socket describing the connection the client.
///\return The exit code of the connector.
int dynamicConnector(Socket::Connection conn){
std::deque<std::string> FlashBuf;
int FlashBufSize = 0;
long long int FlashBufTime = 0;
FLV::Tag tmp; //temporary tag
DTSC::Stream Strm; //Incoming stream buffer.
HTTP::Parser HTTP_R, HTTP_S; //HTTP Receiver en HTTP Sender.
Socket::Connection ss( -1);
std::string streamname;
std::string recBuffer = "";
std::string Quality;
int Segment = -1;
int ReqFragment = -1;
unsigned int lastStats = 0;
conn.setBlocking(false); //do not block on conn.spool() when no data is available
while (conn.connected()){
if (conn.spool() || conn.Received().size()){
//make sure it ends in a \n
if ( *(conn.Received().get().rbegin()) != '\n'){
std::string tmp = conn.Received().get();
conn.Received().get().clear();
if (conn.Received().size()){
conn.Received().get().insert(0, tmp);
}else{
conn.Received().append(tmp);
}
}
if (HTTP_R.Read(conn.Received().get())){
#if DEBUG >= 5
std::cout << "Received request: " << HTTP_R.getUrl() << std::endl;
#endif
conn.setHost(HTTP_R.GetHeader("X-Origin"));
streamname = HTTP_R.GetHeader("X-Stream");
if ( !ss){
ss = Util::Stream::getStream(streamname);
if ( !ss.connected()){
HTTP_S.Clean();
HTTP_S.SetBody("No such stream is available on the system. Please try again.\n");
conn.SendNow(HTTP_S.BuildResponse("404", "Not found"));
continue;
}
ss.setBlocking(false);
//make sure metadata is received
while ( !Strm.metadata && ss.connected()){
if (ss.spool()){
while (Strm.parsePacket(ss.Received())){
//do nothing
}
}
}
}
if (HTTP_R.url.find(".abst") != std::string::npos){
HTTP_S.Clean();
HTTP_S.SetBody(dynamicBootstrap(streamname, Strm.metadata));
HTTP_S.SetHeader("Content-Type", "binary/octet");
HTTP_S.SetHeader("Cache-Control", "no-cache");
conn.SendNow(HTTP_S.BuildResponse("200", "OK"));
HTTP_R.Clean(); //clean for any possible next requests
continue;
}
if (HTTP_R.url.find("f4m") == std::string::npos){
Quality = HTTP_R.url.substr(HTTP_R.url.find("/", 10) + 1);
Quality = Quality.substr(0, Quality.find("Seg"));
int temp;
temp = HTTP_R.url.find("Seg") + 3;
Segment = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find("-", temp) - temp).c_str());
temp = HTTP_R.url.find("Frag") + 4;
ReqFragment = atoi(HTTP_R.url.substr(temp).c_str());
#if DEBUG >= 5
printf("Quality: %s, Seg %d Frag %d\n", Quality.c_str(), Segment, ReqFragment);
#endif
if (Strm.metadata.isMember("live")){
int seekable = Strm.canSeekFrame(ReqFragment);
if (seekable == 0){
// iff the fragment in question is available, check if the next is available too
seekable = Strm.canSeekFrame(ReqFragment + 1);
}
if (seekable < 0){
HTTP_S.Clean();
HTTP_S.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
conn.SendNow(HTTP_S.BuildResponse("412", "Fragment out of range"));
HTTP_R.Clean(); //clean for any possible next requests
std::cout << "Fragment @ F" << ReqFragment << " too old (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
continue;
}
if (seekable > 0){
HTTP_S.Clean();
HTTP_S.SetBody("Proxy, re-request this in a second or two.\n");
conn.SendNow(HTTP_S.BuildResponse("208", "Ask again later"));
HTTP_R.Clean(); //clean for any possible next requests
std::cout << "Fragment @ F" << ReqFragment << " not available yet (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
continue;
}
//.........这里部分代码省略.........
示例12: parseChunk
//.........这里部分代码省略.........
break;
case 6:
fprintf(stderr, "CTRL: UCM PingRequest %i\n", ntohl(*((int*)(next.data.c_str()+2))));
break;
case 7:
fprintf(stderr, "CTRL: UCM PingResponse %i\n", ntohl(*((int*)(next.data.c_str()+2))));
break;
default:
fprintf(stderr, "CTRL: UCM Unknown (%hi)\n", ucmtype);
break;
}
#endif
}
break;
case 5: //window size of other end
#if DEBUG >= 5
fprintf(stderr, "CTRL: Window size\n");
#endif
RTMPStream::rec_window_size = ntohl(*(int*)next.data.c_str());
RTMPStream::rec_window_at = RTMPStream::rec_cnt;
Socket.Send(RTMPStream::SendCTL(3, RTMPStream::rec_cnt)); //send ack (msg 3)
break;
case 6:
#if DEBUG >= 5
fprintf(stderr, "CTRL: Set peer bandwidth\n");
#endif
//4 bytes window size, 1 byte limit type (ignored)
RTMPStream::snd_window_size = ntohl(*(int*)next.data.c_str());
Socket.Send(RTMPStream::SendCTL(5, RTMPStream::snd_window_size)); //send window acknowledgement size (msg 5)
break;
case 8: //audio data
case 9: //video data
case 18: //meta data
if (ss.connected()){
if (streamReset){
//reset push data to empty, in case stream properties change
meta_out.null();
prebuffer.str("");
sending = false;
counter = 0;
streamReset = false;
}
F.ChunkLoader(next);
JSON::Value pack_out = F.toJSON(meta_out);
if ( !pack_out.isNull()){
if ( !sending){
counter++;
if (counter > 8){
sending = true;
ss.SendNow(meta_out.toNetPacked());
ss.SendNow(prebuffer.str().c_str(), prebuffer.str().size()); //write buffer
prebuffer.str(""); //clear buffer
ss.SendNow(pack_out.toNetPacked());
}else{
prebuffer << pack_out.toNetPacked();
}
}else{
ss.SendNow(pack_out.toNetPacked());
}
}
}else{
#if DEBUG >= 5
fprintf(stderr, "Received useless media data\n");
#endif
Socket.close();
}
示例13: SendResponse
/// After receiving a header with this object, this function call will:
/// - Forward the headers to the 'to' Socket::Connection.
/// - Retrieve all the body from the 'from' Socket::Connection.
/// - Forward those contents as-is to the 'to' Socket::Connection.
/// It blocks until completed or either of the connections reaches an error state.
void HTTP::Parser::Proxy(Socket::Connection & from, Socket::Connection & to) {
SendResponse(url, method, to);
if (getChunks) {
unsigned int proxyingChunk = 0;
while (to.connected() && from.connected()) {
if ((from.Received().size() && (from.Received().size() > 1 || *(from.Received().get().rbegin()) == '\n')) || from.spool()) {
if (proxyingChunk) {
while (proxyingChunk && from.Received().size()) {
unsigned int toappend = from.Received().get().size();
if (toappend > proxyingChunk) {
toappend = proxyingChunk;
to.SendNow(from.Received().get().c_str(), toappend);
from.Received().get().erase(0, toappend);
} else {
to.SendNow(from.Received().get());
from.Received().get().clear();
}
proxyingChunk -= toappend;
}
} else {
//Make sure the received data ends in a newline (\n).
if (*(from.Received().get().rbegin()) != '\n') {
if (from.Received().size() > 1) {
//make a copy of the first part
std::string tmp = from.Received().get();
//clear the first part, wiping it from the partlist
from.Received().get().clear();
from.Received().size();
//take the now first (was second) part, insert the stored part in front of it
from.Received().get().insert(0, tmp);
} else {
Util::sleep(100);
}
if (*(from.Received().get().rbegin()) != '\n') {
continue;
}
}
//forward the size and any empty lines
to.SendNow(from.Received().get());
std::string tmpA = from.Received().get().substr(0, from.Received().get().size() - 1);
while (tmpA.find('\r') != std::string::npos) {
tmpA.erase(tmpA.find('\r'));
}
unsigned int chunkLen = 0;
if (!tmpA.empty()) {
for (unsigned int i = 0; i < tmpA.size(); ++i) {
chunkLen = (chunkLen << 4) | unhex(tmpA[i]);
}
if (chunkLen == 0) {
getChunks = false;
to.SendNow("\r\n", 2);
return;
}
proxyingChunk = chunkLen;
}
from.Received().get().clear();
}
} else {
Util::sleep(100);
}
}
} else {
unsigned int bodyLen = length;
while (bodyLen > 0 && to.connected() && from.connected()) {
if (from.Received().size() || from.spool()) {
if (from.Received().get().size() <= bodyLen) {
to.SendNow(from.Received().get());
bodyLen -= from.Received().get().size();
from.Received().get().clear();
} else {
to.SendNow(from.Received().get().c_str(), bodyLen);
from.Received().get().erase(0, bodyLen);
bodyLen = 0;
}
} else {
Util::sleep(100);
}
}
}
}
示例14: parseAMFCommand
///\brief Parses a single AMF command message, and sends a direct response through sendCommand().
///\param amfData The received request.
///\param messageType The type of message.
///\param streamId The ID of the AMF stream.
void parseAMFCommand(AMF::Object & amfData, int messageType, int streamId){
#if DEBUG >= 5
fprintf(stderr, "Received command: %s\n", amfData.Print().c_str());
#endif
#if DEBUG >= 8
fprintf(stderr, "AMF0 command: %s\n", amfData.getContentP(0)->StrValue().c_str());
#endif
if (amfData.getContentP(0)->StrValue() == "connect"){
double objencoding = 0;
if (amfData.getContentP(2)->getContentP("objectEncoding")){
objencoding = amfData.getContentP(2)->getContentP("objectEncoding")->NumValue();
}
#if DEBUG >= 6
int tmpint;
if (amfData.getContentP(2)->getContentP("videoCodecs")){
tmpint = (int)amfData.getContentP(2)->getContentP("videoCodecs")->NumValue();
if (tmpint & 0x04){
fprintf(stderr, "Sorensen video support detected\n");
}
if (tmpint & 0x80){
fprintf(stderr, "H264 video support detected\n");
}
}
if (amfData.getContentP(2)->getContentP("audioCodecs")){
tmpint = (int)amfData.getContentP(2)->getContentP("audioCodecs")->NumValue();
if (tmpint & 0x04){
fprintf(stderr, "MP3 audio support detected\n");
}
if (tmpint & 0x400){
fprintf(stderr, "AAC audio support detected\n");
}
}
#endif
app_name = amfData.getContentP(2)->getContentP("tcUrl")->StrValue();
app_name = app_name.substr(app_name.find('/', 7) + 1);
RTMPStream::chunk_snd_max = 4096;
Socket.Send(RTMPStream::SendCTL(1, RTMPStream::chunk_snd_max)); //send chunk size max (msg 1)
Socket.Send(RTMPStream::SendCTL(5, RTMPStream::snd_window_size)); //send window acknowledgement size (msg 5)
Socket.Send(RTMPStream::SendCTL(6, RTMPStream::rec_window_size)); //send rec window acknowledgement size (msg 6)
Socket.Send(RTMPStream::SendUSR(0, 1)); //send UCM StreamBegin (0), stream 1
//send a _result reply
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "_result")); //result success
amfReply.addContent(amfData.getContent(1)); //same transaction ID
amfReply.addContent(AMF::Object("")); //server properties
amfReply.getContentP(2)->addContent(AMF::Object("fmsVer", "FMS/3,5,5,2004"));
amfReply.getContentP(2)->addContent(AMF::Object("capabilities", (double)31));
amfReply.getContentP(2)->addContent(AMF::Object("mode", (double)1));
amfReply.addContent(AMF::Object("")); //info
amfReply.getContentP(3)->addContent(AMF::Object("level", "status"));
amfReply.getContentP(3)->addContent(AMF::Object("code", "NetConnection.Connect.Success"));
amfReply.getContentP(3)->addContent(AMF::Object("description", "Connection succeeded."));
amfReply.getContentP(3)->addContent(AMF::Object("clientid", 1337));
amfReply.getContentP(3)->addContent(AMF::Object("objectEncoding", objencoding));
//amfReply.getContentP(3)->addContent(AMF::Object("data", AMF::AMF0_ECMA_ARRAY));
//amfReply.getContentP(3)->getContentP(4)->addContent(AMF::Object("version", "3,5,4,1004"));
sendCommand(amfReply, messageType, streamId);
//send onBWDone packet - no clue what it is, but real server sends it...
//amfReply = AMF::Object("container", AMF::AMF0_DDV_CONTAINER);
//amfReply.addContent(AMF::Object("", "onBWDone"));//result
//amfReply.addContent(amfData.getContent(1));//same transaction ID
//amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL));//null
//sendCommand(amfReply, messageType, streamId);
return;
} //connect
if (amfData.getContentP(0)->StrValue() == "createStream"){
//send a _result reply
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "_result")); //result success
amfReply.addContent(amfData.getContent(1)); //same transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //null - command info
amfReply.addContent(AMF::Object("", (double)1)); //stream ID - we use 1
sendCommand(amfReply, messageType, streamId);
Socket.Send(RTMPStream::SendUSR(0, 1)); //send UCM StreamBegin (0), stream 1
return;
} //createStream
if ((amfData.getContentP(0)->StrValue() == "closeStream") || (amfData.getContentP(0)->StrValue() == "deleteStream")){
if (ss.connected()){
ss.close();
}
return;
}
if ((amfData.getContentP(0)->StrValue() == "FCUnpublish") || (amfData.getContentP(0)->StrValue() == "releaseStream")){
// ignored
return;
}
if ((amfData.getContentP(0)->StrValue() == "FCPublish")){
//send a FCPublic reply
AMF::Object amfReply("container", AMF::AMF0_DDV_CONTAINER);
amfReply.addContent(AMF::Object("", "onFCPublish")); //status reply
amfReply.addContent(AMF::Object("", 0, AMF::AMF0_NUMBER)); //same transaction ID
amfReply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //null - command info
amfReply.addContent(AMF::Object("")); //info
amfReply.getContentP(3)->addContent(AMF::Object("code", "NetStream.Publish.Start"));
amfReply.getContentP(3)->addContent(AMF::Object("description", "Please followup with publish command..."));
sendCommand(amfReply, messageType, streamId);
//.........这里部分代码省略.........
示例15: rtmpConnector
///\brief Main function for the RTMP Connector
///\param conn A socket describing the connection the client.
///\return The exit code of the connector.
int rtmpConnector(Socket::Connection conn){
Socket = conn;
Socket.setBlocking(false);
FLV::Tag tag, init_tag;
DTSC::Stream Strm;
while ( !Socket.Received().available(1537) && Socket.connected()){
Socket.spool();
Util::sleep(5);
}
RTMPStream::handshake_in = Socket.Received().remove(1537);
RTMPStream::rec_cnt += 1537;
if (RTMPStream::doHandshake()){
Socket.SendNow(RTMPStream::handshake_out);
while ( !Socket.Received().available(1536) && Socket.connected()){
Socket.spool();
Util::sleep(5);
}
Socket.Received().remove(1536);
RTMPStream::rec_cnt += 1536;
#if DEBUG >= 5
fprintf(stderr, "Handshake succcess!\n");
#endif
}else{
#if DEBUG >= 5
fprintf(stderr, "Handshake fail!\n");
#endif
return 0;
}
unsigned int lastStats = 0;
bool firsttime = true;
while (Socket.connected()){
if (Socket.spool() || firsttime){
parseChunk(Socket.Received());
firsttime = false;
}else{
Util::sleep(1); //sleep 1ms to prevent high CPU usage
}
if (ready4data){
if ( !inited){
//we are ready, connect the socket!
ss = Util::Stream::getStream(streamName);
if ( !ss.connected()){
#if DEBUG >= 1
fprintf(stderr, "Could not connect to server!\n");
#endif
Socket.close(); //disconnect user
break;
}
ss.setBlocking(false);
Strm.waitForMeta(ss);
//find first audio and video tracks
for (JSON::ObjIter objIt = Strm.metadata["tracks"].ObjBegin(); objIt != Strm.metadata["tracks"].ObjEnd(); objIt++){
if (videoID == -1 && objIt->second["type"].asStringRef() == "video"){
videoID = objIt->second["trackid"].asInt();
}
if (audioID == -1 && objIt->second["type"].asStringRef() == "audio"){
audioID = objIt->second["trackid"].asInt();
}
}
//select the tracks and play
std::stringstream cmd;
cmd << "t";
if (videoID != -1){
cmd << " " << videoID;
}
if (audioID != -1){
cmd << " " << audioID;
}
cmd << "\np\n";
ss.SendNow(cmd.str().c_str());
inited = true;
}
if (inited && !noStats){
long long int now = Util::epoch();
if (now != lastStats){
lastStats = now;
ss.SendNow(Socket.getStats("RTMP"));
}
}
if (ss.spool()){
while (Strm.parsePacket(ss.Received())){
if (playTransaction != -1){
//send a status reply
AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
amfreply.addContent(AMF::Object("", "onStatus")); //status reply
amfreply.addContent(AMF::Object("", (double)playTransaction)); //same transaction ID
amfreply.addContent(AMF::Object("", (double)0, AMF::AMF0_NULL)); //null - command info
amfreply.addContent(AMF::Object("")); //info
amfreply.getContentP(3)->addContent(AMF::Object("level", "status"));
amfreply.getContentP(3)->addContent(AMF::Object("code", "NetStream.Play.Reset"));
amfreply.getContentP(3)->addContent(AMF::Object("description", "Playing and resetting..."));
amfreply.getContentP(3)->addContent(AMF::Object("details", "DDV"));
amfreply.getContentP(3)->addContent(AMF::Object("clientid", (double)1337));
//.........这里部分代码省略.........