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

📄 main_loop.c

📁 一个很棒的视频服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
	return 1;      }      /* send a seperator */      sep_data = get_seperator_text( &sep_size );      databuf_buf_set( cinfo->writebuf, sep_data, sep_size );    }    break;  case 1:  /* Keep feeding data to the client */    break;  }  return 0;}staticvoid client_remove( list_t *client_sockets, ClientInfo *cinfo ){  lnode_t *node;  for( node = list_first( client_sockets ); node != NULL; node=node->next ){    if( node->data == cinfo ) {      list_delete( client_sockets, node );      lnode_destroy( node );      return;    }  }}staticvoid sighandler( int signum ){  camserv_log( MODNAME, "Received signal: %d",	   signum );  if( signum == SIGPIPE )    return;  camserv_log( MODNAME, "Aborting!");  Abort = 1;}staticvoid setup_signals(){  signal( SIGTERM, sighandler );  camserv_log( MODNAME, "Setup signals");}int main_loop( CamConfig *ccfg, Socket *picture_sock, char *picture_mem  ){  Socket *listen_socket;  SockSet *readset = NULL, *writeset = NULL;  list_t *client_sockets;  lnode_t *node;  int cfg_listen_port, highest_fd, picture_client_ready;  int num_sclients, num_clients;  ClientInfo *clientinfo, *clientinfo2;  if( (client_sockets = list_create( -1 )) == NULL)    return -1;  cfg_listen_port = camconfig_query_def_int( ccfg, SEC_SOCKET, 					     "listen_port",					     CAMCONFIG_DEF_LISTEN_PORT );  if( (readset = sockset_new()) == NULL ||      (writeset = sockset_new()) == NULL )  {    camserv_log( MODNAME, "Error allocating memory for socksets!");    if( readset ) sockset_dest( readset );    if( writeset ) sockset_dest( writeset );    list_destroy( client_sockets );    return -1;  }  if((listen_socket = socket_serve_tcp( NULL, cfg_listen_port, 100 )) == NULL )  {      camserv_log( MODNAME, "Error setting up socket on port \"%d\".  Exiting",	       cfg_listen_port  );      list_destroy( client_sockets );      sockset_dest( readset );      sockset_dest( writeset );      return -1;  }  highest_fd = MAX( socket_query_fd( listen_socket ), 		    socket_query_fd( picture_sock ));  clientinfo = clientinfo_new( listen_socket );  clientinfo2 = clientinfo_new( picture_sock );  if( !clientinfo || !clientinfo2 ||      sockset_add_fd( readset, listen_socket, clientinfo ) == -1 ||      sockset_add_fd( readset, picture_sock, clientinfo2 ) == -1 )  {    camserv_log( MODNAME, "Error adding initial sockets to sockset!");    sockset_dest( readset );    sockset_dest( writeset );    if( clientinfo )  clientinfo_dest( clientinfo );    if( clientinfo2 ) clientinfo_dest( clientinfo2 );    list_destroy( client_sockets );    return -1;  }  num_clients = 0;  num_sclients = 0;  picture_client_ready = 1;  setup_signals();  Abort = 0;  while( !Abort ){    int sel_res, i, nset_socks;    void **set_socks;    /* Only need to execute this if we have a streaming client */    if( (num_sclients > 0) && picture_client_ready == 1 ){      send( socket_query_fd( picture_sock ), "0", sizeof( "0" ), 0 );      picture_client_ready = 0;    }    sockset_reset( readset );    sockset_reset( writeset );    sel_res = sockset_select( highest_fd + 1, readset, writeset, NULL );    /* Service the event */    if( sel_res == -1 ){      camserv_log( MODNAME, "select() failure: %s", strerror( errno ));      break;    } else if( sel_res == 0 ){      camserv_log( MODNAME, "Unexpected select() fall through!" );      continue;    }     /* Readable sockets */    set_socks = sockset_query_socks( readset );    nset_socks = sockset_query_nsocks( readset );    for( i=0; i< nset_socks; i++ ){      ClientInfo *new_cinfo;      clientinfo = set_socks[ i ];      if( clientinfo->socket == listen_socket ) {	/* New client */	if( (new_cinfo = accept_client( listen_socket )) == NULL )	  continue;	if( (node = lnode_create( new_cinfo )) == NULL ){	  clientinfo_dest( new_cinfo );	  continue;	}	if( sockset_add_fd( readset, new_cinfo->socket, new_cinfo ) == -1 ){	  camserv_log( MODNAME, "Failed to add socket %d to socket read set!",		   socket_query_fd( new_cinfo->socket ));	  clientinfo_dest( new_cinfo );	  lnode_destroy( node );	  continue;	}	if( socket_query_fd( new_cinfo->socket ) > highest_fd )	  highest_fd = socket_query_fd( new_cinfo->socket );	list_append( client_sockets, node );	num_clients++;	/* Init resource limit for this client */	new_cinfo->create_time = time( NULL );	new_cinfo->bytes       = 0;	new_cinfo->frames      = 0;	new_cinfo->max_seconds = camconfig_query_def_int( ccfg, SEC_SOCKET,							  "max_seconds", 0 );	new_cinfo->max_bytes   = camconfig_query_def_int( ccfg, SEC_SOCKET,							  "max_bytes", 0 );	new_cinfo->max_frames  = camconfig_query_def_int( ccfg, SEC_SOCKET,							  "max_frames", 0 );	/* Send fresh request for a picture */	send( socket_query_fd( picture_sock ), "0", sizeof( "0" ), 0 );	picture_client_ready = 0;	/* Put this read socket on hold until the picture comes back */	sockset_hold( readset, new_cinfo->socket );	      } else {	char cmdbuf[ 1024 ];	int readlen;	clientinfo = set_socks[ i ];	/* Regular joe client, set readable */	if( (readlen = read( socket_query_fd( clientinfo->socket), cmdbuf, 			     sizeof( cmdbuf ) - 1)) <= 0 )	{	  camserv_log( MODNAME, "Closing socket: %s", 		       socket_query_remote_name( clientinfo->socket ));	  if (clientinfo->client_type == CLIENT_T_BROWSER ||	      clientinfo->client_type == CLIENT_T_PROXY) {	      num_sclients--;	  }	  client_remove( client_sockets, clientinfo );	  sockset_del_fd( readset, clientinfo->socket );	  sockset_unhold_all( writeset );	  sockset_del_fd( writeset, clientinfo->socket );	  clientinfo_dest( clientinfo );	  num_clients--;	} else {	  if( clientinfo->socket == picture_sock ) {	    if( dispatch_pictaker( cmdbuf, picture_mem ) == -1 )	      camserv_log( MODNAME, "Pictaker dispatch failure!");	    sockset_unhold_all( writeset );	    /* Release the read hold as the picture has now been taken */	    sockset_unhold_all( readset );	    picture_client_ready = 1;	  } else {	    /* Information from a regular client */	    cmdbuf[ readlen ] = '\0';	    if( clientinfo->client_type == CLIENT_T_UNINIT ) {	      char *preamble;	      size_t pre_size;	      /* Figure out what type of client we have */	      if( !strncmp( cmdbuf, "GET", 3 )) {		if( strstr( cmdbuf, "/singleframe" )) {		  clientinfo->client_type = CLIENT_T_SINGLE;		} else {		  clientinfo->client_type = CLIENT_T_BROWSER;		  num_sclients++;	        }	      } else if( !strncmp( cmdbuf, "PROXY", 5 )) {		clientinfo->client_type = CLIENT_T_PROXY;		/* Here we are in the same state as being done writing a pic */		clientinfo->state       = CINFO_STATE_PICTURE;		num_sclients++;			databuf_buf_set( clientinfo->writebuf, NULL, 0 ); 	      } else 		clientinfo->client_type = CLIENT_T_BROWSER;	      if( clientinfo->client_type != CLIENT_T_PROXY ) {		/* Send the initial preamble.  Only now we can decide which 		   type of preamble to send (single vs. multi-part) */		if( clientinfo->client_type == CLIENT_T_SINGLE )		  preamble = get_single_preamble_text( &pre_size );		else		  preamble = get_multi_preamble_text( &pre_size );		databuf_buf_set( clientinfo->writebuf, preamble, pre_size );	      }	      if( sockset_add_fd( writeset, clientinfo->socket, 				  clientinfo ) == -1 )	      {  		  camserv_log( MODNAME, "Failed to add socket %d to write set!",			   socket_query_fd( clientinfo->socket ));	      }	  } 	}       }     }   }     if( set_socks != NULL ) free( set_socks );    /* Writable sockets */    set_socks = sockset_query_socks( writeset );    nset_socks = sockset_query_nsocks( writeset );    for( i=0; i< nset_socks; i++ ){      ClientInfo *cinfo;      cinfo = set_socks[ i ];      if( cinfo->client_type == CLIENT_T_BROWSER ||	  cinfo->client_type == CLIENT_T_SINGLE )       {	int result;	if( (result = write_regular_client( cinfo, writeset )) != 0 ){	  /* result: 1=close requested, -1=error detected */	  if( result == -1 )	    camserv_log( MODNAME, "Databuf write error on socket: %s\n",			 socket_query_remote_name( cinfo->socket ));	  	  if (cinfo->client_type == CLIENT_T_BROWSER) {	      num_sclients--;	  }	  client_remove( client_sockets, cinfo );	  sockset_del_fd( readset, cinfo->socket );	  sockset_del_fd( writeset, cinfo->socket );	  clientinfo_dest( cinfo );	  num_clients--;	}      } else {	if( write_proxy_client( cinfo, writeset ) == -1 ){	  camserv_log( MODNAME, "Databuf write error on socket: %d",		   socket_query_fd( cinfo->socket ));	  /* Should be proxy, but better check */	  if (cinfo->client_type == CLIENT_T_PROXY) {	      num_sclients--;	  }	  client_remove( client_sockets, cinfo );	  sockset_del_fd( readset, cinfo->socket );	  sockset_del_fd( writeset, cinfo->socket );	  clientinfo_dest( cinfo );	  num_clients--;	}      }    }    if( set_socks != NULL ) free( set_socks );  }  camserv_log( MODNAME, "Aborting.");  sockset_dest( readset );  sockset_dest( writeset );  for( node = list_first( client_sockets) ; node;        node=list_next( client_sockets, node ))  {    clientinfo_dest( node->data );  }  /* Tell the picture taker to get out!  Get out! */  camserv_log( MODNAME, "Closing picture taker");  send( socket_query_fd( picture_sock ), "9", sizeof( "9" ), 0 );  sleep( 3 );  camserv_log( MODNAME, "done\n");  list_destroy_nodes( client_sockets );  list_destroy( client_sockets );  socket_dest( listen_socket );  return 0;}

⌨️ 快捷键说明

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