⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 relay.c

📁 一个很棒的视频服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
    cp = "";    len = 0;    cldata->proxycldata.proxystate = PROXYCLSTATE_SEND_PICTURE;    cldata->proxycldata.management_data = NULL;  } else {    camserv_log( MODNAME, "Unknown client state: \"%d\"", cldata->clienttype );    cp = "";    len = 0;  }  databuf_buf_set( cldata->writebuf, cp, len );}/* * relay_client_read:  Called by the sockfield loop when a socket has become *                     readable -- On a client of which we have not identified *                     prior, we determine their type by their initial msg. *                     Otherwise on known sockets we attempt to read all the *                     data we are currently trying to get from them, then *                     dispatch them to the correct handling procedures  *                     (camserv, vs. client). *                      * Arguments:          Standard sockfield callback arguments * * Return Values:      Returns one of SOCKFIELD_* */staticint relay_client_read( SockField_Data *sfdata, Socket *sock, void *cldata ){  ClientData *clientdata = cldata;  int readres;  char sparebuf[ 1024 ];  if( clientdata->clienttype == CLIENT_T_UNK ){    read( socket_query_fd( sock ), sparebuf, sizeof( sparebuf ) );    sparebuf[ sizeof( sparebuf ) - 1 ] = '\0';    /* Client initializing itself */    if( !strncmp( sparebuf, "GET", 3 ) ){      if( strstr( sparebuf, "/singleframe" ))	clientdata->clienttype = CLIENT_T_SINGLE;      else	clientdata->clienttype = CLIENT_T_BROWSER;    } else if( !strncmp( sparebuf, "PROXY", 5 )) {      clientdata->clienttype = CLIENT_T_PROXY;    } else {      clientdata->clienttype = CLIENT_T_BROWSER;    }    databuf_buf_set( clientdata->readbuf, &clientdata->junkbuf[ 0 ],		     sizeof( clientdata->junkbuf ));    set_client_writebuf( clientdata );    sock_field_unhold_write( sfdata );    return SOCKFIELD_OK;  }  readres = databuf_read( clientdata->readbuf, socket_query_fd( sock ));  if( readres == -1 ) return SOCKFIELD_CLOSE;  if( readres ==  1 ) return SOCKFIELD_OK;  if( clientdata->clienttype == CLIENT_T_CAMSERV )    return read_camera( sfdata, sock, clientdata );  else    return read_client( sfdata, sock, clientdata );        return SOCKFIELD_OK;}/* * write_camera:  Called when our camserv socket is set to writeable.  For *                most of the time we will just put ourselves on hold, however *                the initial connection with the camserv requires us to *                send the PROXY message. * * Return values:  Returns one of SOCKFIELD_* */staticint write_camera( SockField_Data *sfdata, Socket *sock, ClientData *cldata ){  if( cldata->camdata.camstate != CAMSTATE_SEND_PROXY ){    sock_field_hold_write( sfdata, sock );    return SOCKFIELD_OK;  }  /* Here we have just initialized our proxy with the connected camera.  So     we put ourselves in a 'read' mode for the rest of the period */  cldata->camdata.camstate = CAMSTATE_RECV_SIZE;  databuf_buf_set( cldata->readbuf, &cldata->camdata.picsize,		   sizeof( cldata->camdata.picsize ) );  return SOCKFIELD_OK;}/* * write_client_proxy:  Called when a client (who has previously identified *                      itself as a proxy) has become writeable.  Depending *                      on the current state of the proxy, a picture will *                      either be snagged from the management bins, or  *                      the picture will be sent. * * Return values:       Returns one of SOCKFIELD_* */staticint write_client_proxy( SockField_Data *sfdata, Socket *sock, 			ClientData *cldata ){  if( cldata->proxycldata.proxystate == PROXYCLSTATE_SEND_PICTURE )  {    char *pic_data;    size_t pic_size;    int pic_id;    /* Just finished sending a picture */    if( cldata->proxycldata.management_data &&	manager_dest_client( cldata->proxycldata.management_data ) == -1 )      camserv_log( MODNAME, "Error destroying client proxy management!");    /* Get a new picture to send */    cldata->proxycldata.management_data =       manager_new_client( &pic_data, &pic_size, &pic_id );    if( cldata->proxycldata.management_data == NULL ){      camserv_log( MODNAME, "Error managing client proxy!  "		   "(no pictures may be available yet)" );      sock_field_hold_write( sfdata, sock );      return SOCKFIELD_OK;    }    if( pic_id == cldata->proxycldata.last_pic_id ) { /* Proxy read too fast */      manager_dest_client( cldata->proxycldata.management_data );      cldata->proxycldata.management_data = NULL;      sock_field_hold_write( sfdata, sock );      return SOCKFIELD_OK;    }    cldata->proxycldata.proxystate = PROXYCLSTATE_SEND_PICSIZE;    cldata->proxycldata.picsize = htonl( pic_size );    cldata->proxycldata.pic_data = pic_data;    cldata->proxycldata.last_pic_id = pic_id;    databuf_buf_set( cldata->writebuf, 		     &cldata->proxycldata.picsize, 		     sizeof( cldata->proxycldata.picsize ));  } else {    /* Else just finished sending the picture size */    cldata->proxycldata.proxystate = PROXYCLSTATE_SEND_PICTURE;    databuf_buf_set( cldata->writebuf, 		     cldata->proxycldata.pic_data,		     ntohl( cldata->proxycldata.picsize ));  }      return SOCKFIELD_OK;}/* * write_client_regular:  Called when a regular client has been set writeable. *                        in such a case we switch between all of the different *                        states of a client and send the appropriate thing. * * Return values:         Returns one of SOCKFIELD_* */staticint write_client_regular( SockField_Data *sfdata, Socket *sock,			  ClientData *cldata ){  if( cldata->browserdata.browserstate == BROWSERSTATE_SEND_PREAMBLE ||      cldata->browserdata.browserstate == BROWSERSTATE_SEND_SEPERATOR )  {    char *pic_data;    size_t pic_size;    int pic_id;    cldata->browserdata.management_data =       manager_new_client( &pic_data, &pic_size, &pic_id );    if( cldata->browserdata.management_data == NULL ){      camserv_log( MODNAME, "Error managing client!  "		   "(no pictures may be available yet)");      sock_field_hold_write( sfdata, sock );      return SOCKFIELD_OK;    }    if( pic_id == cldata->browserdata.last_pic_id ) { /* Client reads fast */      manager_dest_client( cldata->browserdata.management_data );      cldata->browserdata.management_data = NULL;      sock_field_hold_write( sfdata, sock );      return SOCKFIELD_OK;    }    databuf_buf_set( cldata->writebuf, pic_data, pic_size );    cldata->browserdata.last_pic_id = pic_id;    cldata->browserdata.browserstate = BROWSERSTATE_SEND_PICTURE;  } else {    char *sep_data;    size_t sep_size;        if( manager_dest_client( cldata->browserdata.management_data ) == -1 ){      camserv_log( MODNAME, "Error destroying client management!");    }    cldata->browserdata.management_data = NULL;    cldata->browserdata.browserstate = BROWSERSTATE_SEND_SEPERATOR;    sep_data = get_seperator_text( &sep_size );    databuf_buf_set( cldata->writebuf, sep_data, sep_size );  }  return SOCKFIELD_OK;}staticint write_client( SockField_Data *sfdata, Socket *sock, ClientData *cldata ){  /* If client hasn't initialized itself with us yet, put him on hold */  if( cldata->clienttype == CLIENT_T_UNK ){    sock_field_hold_write( sfdata, sock );    return SOCKFIELD_OK;  }  if( cldata->clienttype == CLIENT_T_PROXY )    return write_client_proxy( sfdata, sock, cldata );  else    return write_client_regular( sfdata, sock, cldata );  return SOCKFIELD_OK;}staticint relay_client_write( SockField_Data *sfdata, Socket *sock, void *cldata ){  ClientData *clientdata = cldata;  int writeres;  writeres = databuf_write( clientdata->writebuf, socket_query_fd( sock ));  if( writeres == -1 ) return SOCKFIELD_CLOSE;  if( writeres ==  1 ) return SOCKFIELD_OK;  /* Still data left to write */  /* Else we have written all the data we were supposed to */  if( clientdata->clienttype == CLIENT_T_CAMSERV )     return write_camera( sfdata, sock, clientdata );  else    return write_client( sfdata, sock, clientdata );    return SOCKFIELD_OK;}staticvoid relay_accept( SockField_Data *sfdata, Socket *listen_sock,		   void *sys_cldata ){  ClientData *cldata;  Socket *new_socket;  if( (new_socket = socket_accept( listen_sock )) == NULL ){    camserv_log( MODNAME, "Error accepting new socket!");    return;  }  if( (cldata = client_data_new()) == NULL ){    camserv_log( MODNAME, "Error allocating clientdata!");    socket_dest( new_socket );    return;  }  cldata->clienttype = CLIENT_T_UNK;  if( sock_field_manage_socket( sfdata, new_socket, cldata ) == -1 ){    camserv_log( MODNAME, "Error managing new socket" );    socket_dest( new_socket );    client_data_dest( cldata );    return;  }  camserv_log( MODNAME, "Accepted client: \"%s\"", 	       socket_query_remote_name( new_socket ));}staticvoid relay_timeout( SockField_Data *sfdata, void *sys_cldata ){  RelayData *rdata = sys_cldata;    if( rdata->camera_sock == NULL ) {    camserv_log( MODNAME, "Attempting connect to camserver");    if( relay_connect_camserv( sfdata, rdata ) == -1 ){      camserv_log( MODNAME, "Error connecting to camserv: %s %d",	       rdata->camera_ip, rdata->camera_port );    }  }}int main( int argc, char *argv[] ){  Socket *listen_sock;  int localport, remoteport;  RelayData rdata;  struct timeval retry_time;  if( argc < 3 ) {    fprintf( stderr, "camserv relay v%s - by Jon Travis (jtravis@p00p.org)\n",	     VERSION );    fprintf( stderr, "Syntax: %s <port> <camserv IP> <ccamserv port>\n", 	     argv[ 0 ]);    fprintf( stderr, "\tThe relay will bind port <port> on the localhost\n");    fprintf( stderr, "\tand connect to the camserv port to do the relay.\n");    return -1;  }  signal( SIGPIPE, SIG_IGN );  if( sscanf( argv[1], "%d", &localport ) != 1 ) {    camserv_log( MODNAME, "Error:  port \"%s\" invalid!", argv[ 1 ] );    return -1;  }  if( localport < 1024 )    camserv_log( MODNAME, "Warning:  Port numbers < 1024 shouldn't be used");  if( sscanf( argv[3], "%d", &remoteport ) != 1 ) {    camserv_log( MODNAME, "Error:  camserv port \"%s\" invalid!", argv[3] );    return -1;  }  strncpy( rdata.camera_ip, argv[2], sizeof( rdata.camera_ip ) - 1);  rdata.camera_ip[ sizeof( rdata.camera_ip ) - 1 ] = '\0';  rdata.camera_port = remoteport;  rdata.camera_sock = NULL;  if( (listen_sock = socket_serve_tcp( NULL, localport, BACKLOG )) == NULL ){    camserv_log( MODNAME, "Could not bind local port: %s", 	     strerror( errno ));    return -1;  }  retry_time.tv_sec = 10;  retry_time.tv_usec = 0;  if( sock_field( listen_sock, &rdata, relay_init, relay_accept, 		  relay_client_read, relay_client_write,		  relay_preclose, relay_timeout, &retry_time ) == -1 )  {    socket_dest( listen_sock );    camserv_log( MODNAME, "Camserv relay abnormally terminated");    return -1;  }  socket_dest( listen_sock );  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -