예제 #1
0
파일: net.c 프로젝트: faf0/sws
/**
 * Starts the server and transits into daemon mode, if not in debug mode.
 * Loops forever, accepting stream (TCP)  connections.
 * Child is forked when a client connects.
 *
 * @param flag user-provided flags.
 */
void
run_server(struct flags* flag)
{
  int server_sock;

  /* start listening for clients */
  server_sock = setup_server_socket(flag);

  /* attach signal handlers */
  if (signal(SIGCHLD, server_sig_handler) == SIG_ERR) {
    err(EXIT_FAILURE, "cannot catch SIGCHLD");
  }
  if (signal(SIGHUP, server_sig_handler) == SIG_ERR) {
    err(EXIT_FAILURE, "cannot catch SIGCHUP");
  }

  /* Start accepting connections */
  listen(server_sock, BACKLOG);

  /* daemonize if not in debug mode */
  if (!flag->dflag) {
    if (daemon(1, 1) < 0) {
      errx(EXIT_FAILURE, "cannot transit into daemon mode");
    }
  }

  /* Handle clients */
  do {
    accept_client(flag, server_sock);
  } while (1);

  close(server_sock);
}
예제 #2
0
void run(global_config_struct *global_config) {
	global_resources_struct global_resources;
	
	setup_server_socket(global_config, &global_resources);
	global_resources.bases.transfer_buffer_size = global_config->transfer_buffer_size;
	setup_events(&global_resources);
	listen_server_socket(&global_resources);
	dispatch(&global_resources);
	close_all(&global_resources);
}
예제 #3
0
//--    main()              ///{{{1///////////////////////////////////////////
int main( int argc, char* argv[] )
{
    int serverPort = kServerPort;
    fd_set readfds;
    fd_set writefds;
    int maxFd, activity, sd;

    std::vector<ConnectionData> connections;

    // Did the user specify a port?
    if( 2 == argc )
	{
	    serverPort = atoi(argv[1]);
	}

#	if VERBOSE
    printf( "Attempting to bind to port %d\n", serverPort );
#	endif

    // Set up listening socket - see setup_server_socket() for details.
    int listenfd = setup_server_socket( serverPort );


    if( -1 == listenfd )
	return 1;

    // loop forever
    while( 1 )
	{
	    
	    FD_ZERO(&readfds); // Clear the read socket set
	    FD_ZERO(&writefds); // Clear the read socket set

	    FD_SET(listenfd, &readfds); // Add the listen socket to the read set
	    maxFd = listenfd; // Initially add the listen socket as the maximum file descriptor

	    // Add the client descriptors to the set.
	    for(size_t i = 0; i < connections.size(); i++){
		sd = connections[i].sock;

		if(sd > 0){
		    if(connections[i].state == eConnStateReceiving) //Add connections to the corresponding sets
			FD_SET(sd, &readfds);
		    else if(connections[i].state == eConnStateSending)
			FD_SET(sd, &writefds);
		}

		if(sd > maxFd){ // Change maxFd if the file descriptor of the client is larger than the current maxium
		    maxFd = sd;
		}
	    }


	    activity = select(maxFd + 1, &readfds, &writefds, NULL, NULL); // Perform select to find pending reads and writes

	    if((activity < 0) && (errno != EINTR)){ // Check so that no errors occured.
		printf("select error \n"); // Should we have "else"
	    }

	    if(FD_ISSET(listenfd, &readfds)){ // If there is activity on the listening socket
		// Accept connection and add it to the list.
		if(acceptConnection(&connections, listenfd) == -1)
		    continue;
		continue;
	    }

	    // Loop through all connections and check if they members of a set
	    for(size_t i=0; i<connections.size(); i++){
		sd = connections[i].sock; //Copy the socket descriptor

		bool processFurther = true;
		if(FD_ISSET(sd, &readfds)){

		    while( processFurther && connections[i].state == eConnStateReceiving )
			processFurther = process_client_recv( connections[i] );
		}
		
		else if(FD_ISSET(sd, &writefds)){
		    while( processFurther && connections[i].state == eConnStateSending )
			processFurther = process_client_send( connections[i] );
		}

		if(!processFurther){ // Close the socket if processing is finished
			close(connections[i].sock);
			connections[i].sock = -1;
		}
	    }
	    
	    //Erase all invalid connections
	    connections.erase(std::remove_if(connections.begin(),
                   connections.end(), &is_invalid_connection),connections.end());
	}

    // The program will never reach this part, but for demonstration purposes,
    // we'll clean up the server resources here and then exit nicely.
    close( listenfd );

    return 0;
}
예제 #4
0
파일: tcp.hpp 프로젝트: cybozu/yrmcds
 // Construct a server socket.
 // @bind_addr  A numeric IP address to be bound, or `NULL`.
 // @port       TCP port number to be bound.
 // @on_accept  Callback function.
 // @freebind   true to turn on IP_FREEBIND socket option.
 //
 // This creates a socket and bind it to the given address and port.
 // If `bind_addr` is `NULL`, the socket will listen on any address.
 // Both IPv4 and IPv6 addresses are supported.
 //
 // For each new connection, `on_accept` is called to determine
 // if the new connection need to be closed immediately or
 // to be added to the reactor.  If `on_accept` returns an empty
 // <std::unique_ptr>, the new connection is closed immediately.
 // Otherwise, the new connection is added to the reactor.
 tcp_server_socket(const char* bind_addr, std::uint16_t port,
                   wrapper on_accept, bool freebind):
     resource( setup_server_socket(bind_addr, port, freebind) ),
     m_wrapper(on_accept) {}
예제 #5
0
//--    main()              ///{{{1///////////////////////////////////////////
int main( int argc, char* argv[] )
{
	int serverPort = kServerPort;

	// did the user specify a port?
	if( 2 == argc )
	{
		serverPort = atoi(argv[1]);
	}

#	if VERBOSE
	printf( "Attempting to bind to port %d\n", serverPort );
#	endif

	// set up listening socket - see setup_server_socket() for details.
	int listenfd = setup_server_socket( serverPort );

	if( -1 == listenfd )
		return 1;

	// loop forever
	while( 1 )
	{
		sockaddr_in clientAddr;
		socklen_t addrSize = sizeof(clientAddr);

		// accept a single incoming connection
		int clientfd = accept( listenfd, (sockaddr*)&clientAddr, &addrSize );
		printf("Accepted a new client.. \n");

		if( -1 == clientfd )
		{
			perror( "accept() failed" );
			continue; // attempt to accept a different client.
		}

#			if VERBOSE
		// print some information about the new client
		char buff[128];
		printf( "Connection from %s:%d -> socket %d\n",
			inet_ntop( AF_INET, &clientAddr.sin_addr, buff, sizeof(buff) ),
			ntohs(clientAddr.sin_port),
			clientfd
		);
		fflush( stdout );
#			endif

#			if NONBLOCKING
		// enable non-blocking sends and receives on this socket
		if( !set_socket_nonblocking( clientfd ) )
			continue;
#			endif

		// initialize connection data
		ConnectionData connData;
		memset( &connData, 0, sizeof(connData) );

		connData.sock = clientfd;
		connData.state = eConnStateReceiving;

		// Repeatedly receive and re-send data from the connection. When
		// the connection closes, process_client_*() will return false, no
		// further processing is done.
		bool processFurther = true;
		while( processFurther )
		{
			while( processFurther && connData.state == eConnStateReceiving )
				processFurther = process_client_recv( connData );

			while( processFurther && connData.state == eConnStateSending )
				processFurther = process_client_send( connData );
		}

		// done - close connection
		close( connData.sock );
	}

	// The program will never reach this part, but for demonstration purposes,
	// we'll clean up the server resources here and then exit nicely.
	close( listenfd );

	return 0;
}