LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Handle query strings using socket programming (https://www.linuxquestions.org/questions/programming-9/handle-query-strings-using-socket-programming-774007/)

c00get 12-07-2009 10:52 AM

Handle query strings using socket programming
 
Hi, I need to make a daemon which listens to port 81 for messages like http://localhost/message?command=move&dir=left
So far I made a daemon which serves as a simple stream server: I set up a socket to listen to a non-reserved port (like 9999), but I don't know how to read the query strings.

Linux distro: Kubuntu 9.04
Language: C

David1357 12-07-2009 12:23 PM

Quote:

Originally Posted by c00get (Post 3782873)
So far I made a daemon which serves as a simple stream server: I set up a socket to listen to a non-reserved port (like 9999), but I don't know how to read the query strings.

What have you written so far? Paste your code inside CODE tags.

theNbomr 12-07-2009 12:56 PM

Use netcat (nc) as a listener, and it will print the query that your application will see. From that, you should be able to determine the method you should use to parse the query. The query string will be readable on the standard input stream.
What you are creating is one of the essential ingredients of a web server.
--- rod

c00get 12-08-2009 10:31 AM

Thanks for the replies.

Quote:

Originally Posted by David1357 (Post 3782964)
What have you written so far? Paste your code inside CODE tags.

Code:

#include <stdlib.h>
#include <syslog.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

#define PORT                81
#define MAXBUF                64
#define SLEEP_TIME        3
#define COUNT_MAX        3


int main(void)
{
        pid_t pid, sid;
        int status;

        /* Fork off the parent process */
        pid = fork();
        if (pid < 0)
        {
                syslog(LOG_ERR, "fork(): %m");
                exit(EXIT_FAILURE);
        }
       
    /* If we got a good PID, then
        we can exit the parent process. */
        if (pid > 0)
        {
                exit(EXIT_SUCCESS);
        }

        /* Change the file mode mask */
        umask(0);

        /* Create a new SID for the child process */
        sid = setsid();
        if (sid < 0)
        {
                syslog(LOG_ERR, "setsid(): %m");
                exit(EXIT_FAILURE);
        }

        /* Change the current working directory */
        if ((chdir("/")) < 0)
        {
                syslog(LOG_ERR, "chdir(): %m");
                exit(EXIT_FAILURE);
        }

        /* Close out the standard file descriptors */
        status = close(STDIN_FILENO);
        if (status < 0)
        {
                syslog(LOG_ERR, "close(STDIN_FILENO): %m");
                exit(EXIT_FAILURE);
        }
       
        status = close(STDOUT_FILENO);
        if (status < 0)
        {
                syslog(LOG_ERR, "close(STDOUT_FILENO): %m");
                exit(EXIT_FAILURE);
        }
       
        status = close(STDERR_FILENO);
        if (status < 0)
        {
                syslog(LOG_ERR, "close(STDERR_FILENO): %m");
                exit(EXIT_FAILURE);
        }

        //---------------------------------------------------------------------------
       
        int sockfd, clientfd;
        struct sockaddr_in self, client_addr;
        int addrlen = sizeof(client_addr);
        char buffer[MAXBUF], command[8], param[8];
        int count;

        /* Create streaming socket */
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
        {
                syslog(LOG_ERR, "socket(): %m");
                exit(EXIT_FAILURE);
        }

        /* Initialize address/port structure */
        bzero(&self, sizeof(self));
        self.sin_family = AF_INET;
        self.sin_port = htons(PORT);
        self.sin_addr.s_addr = INADDR_ANY;

        /* Assign a port number to the socket */
        status = bind(sockfd, (struct sockaddr*) &self, sizeof(self));
        if (status < 0)
        {
                syslog(LOG_ERR, "bind(): %m");
                exit(EXIT_FAILURE);
        }
       
        /* Make it a "listening socket" */
        status = listen(sockfd, 20);
        if (status < 0)
        {
                syslog(LOG_ERR, "listen(): %m");
                exit(EXIT_FAILURE);
        }
       
        /* The Big Loop */
        while (1)
        {
                /* Accept a connection (creating a data pipe) */
                count = COUNT_MAX;
                do {
                        clientfd = accept(sockfd, (struct sockaddr*) &client_addr, &addrlen);
                        if (clientfd < 0)
                        {
                                syslog(LOG_ERR, "accept(): %m");
                                count--;
                                sleep(SLEEP_TIME); // Wait
                        }
                } while (status < 0 && count > 0);
                if (count <= 0)
                        exit(EXIT_FAILURE);

                /* Receive message */
                status = recv(clientfd, buffer, MAXBUF, 0);
                if (status < 0)
                        syslog(LOG_ERR, "recv(): %m");
                else if (status > 0)
                {

                }

                /* Close data connection */
                count = COUNT_MAX;
                do {
                        status = close(clientfd);
                        if (status < 0)
                        {
                                syslog(LOG_ERR, "close(clientfd): %m");
                                count--;
                                sleep(SLEEP_TIME); // Wait
                        }
                } while (status < 0 && count > 0);
                if (count <= 0)
                        exit(EXIT_FAILURE);
        }

        /* Clean up */
        count = COUNT_MAX;
        do {
                status = close(sockfd);
                if (status < 0)
                {
                        syslog(LOG_ERR, "close(sockfd): %m");
                        count--;
                        sleep(SLEEP_TIME); // Wait
                }
        } while (status < 0 && count > 0);
        if (count <= 0)
                exit(EXIT_FAILURE);

        /* Everything went well */
        exit(EXIT_SUCCESS);
}

Thanks theNbomr, I'll try that.

David1357 12-08-2009 12:07 PM

You would put your code to handle GET requests in the "else if" clause that you left empty:
Code:

                /* Receive message */
                status = recv(clientfd, buffer, MAXBUF, 0);
                if (status < 0)
                        syslog(LOG_ERR, "recv(): %m");
                else if (status > 0)
                {
                        /****************************************
                        * Put GET request processing here
                        ***************************************/
                }

"buffer" will contain text that looks like
Code:

GET /message?command=move&dir=left HTTP/1.1
Host: 192.168.1.164

I verified this by modifying your program to look like
Code:

#include <stdlib.h>
#include <syslog.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

#define PORT            80
#define MAXBUF          64
#define SLEEP_TIME      3
#define COUNT_MAX      3


int main(void)
{
        pid_t pid, sid;
        int status;

        int sockfd, clientfd;
        struct sockaddr_in self, client_addr;
        int addrlen = sizeof(client_addr);
        char buffer[MAXBUF], command[8], param[8];
        int count;

        /* Create streaming socket */
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
        {
                syslog(LOG_ERR, "socket(): %m");
                exit(EXIT_FAILURE);
        }

        /* Initialize address/port structure */
        bzero(&self, sizeof(self));
        self.sin_family = AF_INET;
        self.sin_port = htons(PORT);
        self.sin_addr.s_addr = INADDR_ANY;

        /* Assign a port number to the socket */
        status = bind(sockfd, (struct sockaddr*) &self, sizeof(self));
        if (status < 0)
        {
                syslog(LOG_ERR, "bind(): %m");
                exit(EXIT_FAILURE);
        }

        /* Make it a "listening socket" */
        status = listen(sockfd, 20);
        if (status < 0)
        {
                syslog(LOG_ERR, "listen(): %m");
                exit(EXIT_FAILURE);
        }

        /* The Big Loop */
        while (1)
        {
                /* Accept a connection (creating a data pipe) */
                count = COUNT_MAX;
                do {
                        clientfd = accept(sockfd, (struct sockaddr*) &client_addr, &addrlen);
                        if (clientfd < 0)
                        {
                                syslog(LOG_ERR, "accept(): %m");
                                count--;
                                sleep(SLEEP_TIME); // Wait
                        }
                } while (status < 0 && count > 0);
                if (count <= 0)
                        exit(EXIT_FAILURE);

                /* Receive message */
                status = recv(clientfd, buffer, MAXBUF, 0);
                if (status < 0)
                        syslog(LOG_ERR, "recv(): %m");
                else if (status > 0)
                {
                        printf("%s\n", buffer);
                }

                /* Close data connection */
                count = COUNT_MAX;
                do {
                        status = close(clientfd);
                        if (status < 0)
                        {
                                syslog(LOG_ERR, "close(clientfd): %m");
                                count--;
                                sleep(SLEEP_TIME); // Wait
                        }
                } while (status < 0 && count > 0);
                if (count <= 0)
                        exit(EXIT_FAILURE);
        }

        /* Clean up */
        count = COUNT_MAX;
        do {
                status = close(sockfd);
                if (status < 0)
                {
                        syslog(LOG_ERR, "close(sockfd): %m");
                        count--;
                        sleep(SLEEP_TIME); // Wait
                }
        } while (status < 0 && count > 0);
        if (count <= 0)
                exit(EXIT_FAILURE);

        /* Everything went well */
        exit(EXIT_SUCCESS);
}


c00get 12-09-2009 12:50 PM

I finally managed to get the query string. I wasn't reading the buffer correctly because I didn't know the format. Thank you for your help.


All times are GMT -5. The time now is 02:44 PM.