Thread: I need to accept and send to more then one connection.

  1. #1
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102

    I need to accept and send to more then one connection.

    Code:
    while(1){
         int addrlen, new_socket;
         addrlen = sizeof(struct sockaddr_in);
         new_socket = accept(socket_desc, (struct sockaddr *)&address, &addrlen);
         if (new_socket<0) {
              fatal("new_socket, Accepting socket_desc");
              exit(EXIT_FAILURE); }
    
         sleep(10);char buffer[256];
         n = read(new_socket,buffer,255);
         if (n < 0) {
              fatal("ERROR reading from socket");
              exit(EXIT_FAILURE); }
         close(socket_desc);exit(EXIT_SUCCESS);
    }
    I just need help taking this code and making it accept multiple,
    connections. Maybe let me know how to send to each individual connection.
    Last edited by errigour; 11-08-2010 at 06:53 PM.

  2. #2
    Registered User
    Join Date
    Jan 2006
    Location
    Europe/Belgrade
    Posts
    78
    You can fork process for each accepted client, you can use threads for each client or you can use multiplexing. For the start, you should read tutorial at Beej's Guide to Network Programming. There, you can find the first and the third approach.

  3. #3
    Registered User errigour's Avatar
    Join Date
    Mar 2009
    Posts
    102

    What exactly does fork do?

    I was looking into that but what does fork do exactly and how could I orginize the connections I receive. and who do I send() and recv() from. could you give me a small example ot something using the code above. to orginize fork(). It would help so much,
    Last edited by errigour; 11-08-2010 at 06:54 PM.

  4. #4
    Registered User
    Join Date
    Jan 2006
    Location
    Europe/Belgrade
    Posts
    78
    fork() makes a copy of the calling process. Here is an example of the server which accepts clients and process them in a separate process (created by forking).

    Code:
    /*
    
    server_forked.c
    ---------------
    
    Forked TCP server, each client is accepted by a separate process.
    Client gets request echo until 'quit' is typed.
    
    Compile with
    	gcc -oserver_forked server_forked.c
    
    */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <sys/wait.h>
    #include <signal.h>
    
    
    /**
    waits all children to finish
    
    @param sig_no  not used
    @return        none
    **/
    void wait_children(int sig_no)
    {
    	while (waitpid((pid_t)-1, NULL, WNOHANG) > 0)
    		;
    }
    
    
    /**
    processes one client
    
    @param client_fd  client socket
    **/
    void process(int client_fd)
    {
    	const int REQUEST_LEN = 1000;
    	char request[REQUEST_LEN];
    
    	memset((void*)request, '\0', REQUEST_LEN);
    
    	while (strncmp(request, "quit", 4))
    	{
    		int result;
    		
    		memset((void*)request, '\0', REQUEST_LEN);
    		result = recv(client_fd, request, REQUEST_LEN, 0);
    		if (result == -1)
    		{
    			fprintf(stderr, "process():getpid()=%d,cannot receive request,ending chat...\n", getpid());
    			break;
    		}
    		else if (result == 0)
    		{
    			printf("process():getpid()=%d,client quitted,ending chat...\n", getpid());
    			break;
    		}
    		printf("process():getpid()=%d,request=%s\n", getpid(), request);
    
    		if (send(client_fd, request, strlen(request), 0) == -1)
    		{
    			fprintf(stderr, "process():getpid()=%d,cannot send response,ending chat...\n", getpid());
    			break;
    		}
    		printf("process():getpid()=%d,echo sent...\n", getpid());
    	}
    	
    	close(client_fd);
    }
    
    
    int main()
    {
    	struct addrinfo* server_address;
    	struct addrinfo hint;
    	int server_fd = 0;
    	const char* PORT = "7000";
    	const unsigned int PENDING_SIZE = 5;
    	struct sigaction signal_action;
    
    	hint.ai_family = 0;
    	hint.ai_socktype = SOCK_STREAM;
    	hint.ai_flags = AI_PASSIVE;
    	hint.ai_protocol = 0;
    	hint.ai_addrlen = 0;
    	hint.ai_canonname = NULL;
    	hint.ai_addr = NULL;
    	hint.ai_next = NULL;
    
    	if (getaddrinfo("localhost", PORT, &hint, &server_address) != 0)
    	{
    		fprintf(stderr, "main():cannot locate host,exiting program...\n");
    		exit(EXIT_FAILURE);
    	}
    
    	server_fd = socket(server_address->ai_family, server_address->ai_socktype, server_address->ai_protocol);
    	if (server_fd == -1)
    	{
    		fprintf(stderr, "main():cannot create socket,exiting program...\n");
    		exit(EXIT_FAILURE);
    	}
    
    	if (bind(server_fd, server_address->ai_addr, server_address->ai_addrlen) == -1)
    	{
    		fprintf(stderr, "main():cannot bind,exiting program...\n");
    		exit(EXIT_FAILURE);
    	}
    
    	freeaddrinfo(server_address);
    
    	if (listen(server_fd, PENDING_SIZE) == -1)
    	{
    		fprintf(stderr, "main():cannot listen,exiting program...\n");
    		exit(EXIT_FAILURE);
    	}
    
    	signal_action.sa_handler = wait_children;
    	sigemptyset(&signal_action.sa_mask);
    	signal_action.sa_flags = SA_RESTART;
    	if (sigaction(SIGCHLD, &signal_action, NULL) == -1)
    	{
    		fprintf(stderr, "main():'sigaction()' failed,exiting program...\n");
    		exit(EXIT_FAILURE);
    	}
    
    	while (1)
    	{
    		struct sockaddr client_address;
    		socklen_t client_address_len = sizeof(struct sockaddr_storage);
    		int client_fd;
    		char addr_buf[INET_ADDRSTRLEN];
    		int pid;
    
    		client_fd = accept(server_fd, &client_address, &client_address_len);
    		if (client_fd == -1)
    		{
    			printf("main():cannot accept client,sleeping...\n");
    			sleep(5);
    		}
    		printf("main():client accepted from:%s\n", inet_ntop(AF_INET, &client_address, addr_buf, INET_ADDRSTRLEN));
    
    		// fork child process for a new client
    
    		pid = fork();
    		if (pid == 0) // child
    		{
    			process(client_fd);
    			close(client_fd);
    			printf("main():ending child...\n");
    			exit(EXIT_SUCCESS);
    		}
    		else if (pid < 0)
    		{
    			fprintf(stderr, "main():cannot fork,sleeping...\n");
    			sleep(5);
    		}
    		close(client_fd);
    	}
    
    	return EXIT_SUCCESS;
    }
    When server socket is created, the forever loop in main() accepts new clients. When a new client has connected, the new child process is forked and process() is called to deal with that client. All send() and recv() are being made here in process(). Once the conversation between client and server is done (client typed "quit"), the communication is finished, socket closed and process() exits. All of the time, server loop in main() accepts new clients in its own process.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Non-blocking socket connection problem
    By cbalu in forum Linux Programming
    Replies: 25
    Last Post: 06-03-2009, 02:15 AM
  2. send and receive byte does not match
    By saipkjai in forum Networking/Device Communication
    Replies: 1
    Last Post: 02-09-2008, 01:09 AM
  3. socket send() exits app unexceptively
    By Kleid-0 in forum C Programming
    Replies: 9
    Last Post: 07-25-2005, 08:29 AM
  4. CString conversion for socket send()
    By WaterNut in forum C++ Programming
    Replies: 13
    Last Post: 04-27-2005, 04:55 PM
  5. async Client/Server app, accept() stalls?
    By JaWiB in forum Networking/Device Communication
    Replies: 14
    Last Post: 01-31-2005, 05:59 PM