Программирование на C: HTTP-запрос не работает постоянно - PullRequest
1 голос
/ 29 апреля 2011

Я новичок в программировании сокетов и сам в.Я написал небольшой фрагмент кода, который считывает необработанные данные из другого интернет-сокета и публикует данные на веб-сервере.полученные данные всегда числовые.однако проблема, по-видимому, заключается в том, что запрос http post выполняется только один раз, вместо того, чтобы выполняться в цикле, и программа завершается.

следующий пример кода

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>

//define server parameters
#define WEBIP       "172.16.100.2"






int main()
{
        //declare variables
        struct sockaddr_in my_addr,client_addr,server_addr;
        struct hostent *server_host;
        int true=1;
        int client_socket_id,server_socket_id;
        int client_id;int sin_size;
        int client_bytes_received;
        char send_data [1024],recv_data[1024],post_data[1024];       

        server_host=gethostbyname(WEBIP2);

        //create a socket to listen to client
        if ((client_socket_id = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
            perror("Error Creating Socket");
            exit(1);
        }
        if (setsockopt(client_socket_id,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1) {
            perror("Setsockopt");
            exit(1);
        }
        //create socket to connect to webserver
        if ((server_socket_id = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
            perror("Error Creating Webserver Socket");
            exit(1);
            }

        my_addr.sin_family = AF_INET;         
        my_addr.sin_port = htons(7070);     
        my_addr.sin_addr.s_addr = INADDR_ANY; 
        //bzero(&(my_addr.sin_zero),8); 
        bzero(&(server_addr.sin_zero),8); 
        server_addr.sin_family = AF_INET;         
        server_addr.sin_port = htons(WEBPORT);     
        server_addr.sin_addr = *((struct in_addr *)server_host->h_addr);





        //bind to a socket
        if (bind(client_socket_id, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1) {
            perror("Unable to bind");
            exit(1);
        }

        //listen to socket
        if (listen(client_socket_id, 5) == -1) {
            perror("Error Listening to Socket");
            exit(1);
        }

        printf("\n\r Waiting for client on port 7070");
        fflush(stdout);


        while(1)
        {  

            sin_size = sizeof(struct sockaddr_in);
            client_id = accept(client_socket_id, (struct sockaddr *)&client_addr,&sin_size);
            printf("\n I got a connection from (%s , %d)",
                   inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));

            //connect to remote server
            if (connect(server_socket_id, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1) 
                {
                    perror("Error Connecting to Web Server");
                    exit(1);
                }


            while(1){

            //send some data to client
            send(client_id,"Hello, World!",13, 0); 
            //receive some data from client
            client_bytes_received=recv(client_id,recv_data,1024,0);
            recv_data[client_bytes_received] = '\0';
            //print received_data
            int c_length=strlen(recv_data)+11;
            printf("\n\rRecieved data (%d bytes %d words)= %s " , client_bytes_received,c_length,recv_data);
            //post dta to webserver
            fflush(stdout);
            bzero(&post_data,1024);
            sprintf(post_data,"POST /environment.php HTTP/1.1\r\n"
                            "Host: 172.16.100.2\r\n"
                            "User-Agent: C Example Client\r\n"
                            "Content-Type: application/x-www-form-urlencoded\r\n"
                            "Content-Length: %d\r\n\r\n"
                            "track_data=%s",c_length,recv_data);
            write(server_socket_id,post_data,strlen(post_data)+1); 
            bzero(&recv_data,1024);


            while((client_bytes_received=read(server_socket_id,recv_data,1024))>0){
            recv_data[client_bytes_received] = '\0';
                if (fputs(recv_data,stdout)==EOF)
                    perror("web server read_error");
                }
            //print received_data
            printf("\n\rRecieved data from webserver (%d)= %s " , client_bytes_received,recv_data);
            //
            bzero(&recv_data,1024);
            fflush(stdout);



         }
        }  
        close(client_id);

    close(client_socket_id);
    return 0;
} 

Ответы [ 2 ]

3 голосов
/ 29 апреля 2011

Я давно не программировал сокеты, поэтому, пожалуйста, потерпите меня. Вам нужно подключиться, обработать, а затем отключить? Это первое, что пришло в голову при чтении вашего кода.

0 голосов
/ 29 апреля 2011

Я удивлен, что эта программа работает. Вы создали блокирующие сокеты, если только вы не работаете в ОС, не поддерживающей POSIX. Вызов подтверждения никогда не должен был возвращаться. Если accept возвращает, это означает, что ваш серверный сокет не может перейти в режим ожидания. Следовательно, все, что вы видите, скорее всего из-за ошибки.

SO_NONBLOCK - опция сокета, которую вы можете использовать для создания неблокирующих сокетов.

Поскольку вы используете одну и ту же процедуру как для клиента, так и для сервера, вы должны использовать select в цикле сокета.

...