C套接字编程:HTTP请求不能连续工作

时间:2011-04-29 11:51:58

标签: c http sockets networking request

我是c socket编程的新手和c本身。我编写了一小段代码,从另一个Internet套接字读取原始输入并将数据发布到Web服务器。收到的数据始终是数字。但问题似乎是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 个答案:

答案 0 :(得分:3)

我多年没有做套接字编程,所以请耐心等待。您需要连接,处理,然后断开连接吗?这是读取代码时首先想到的。

答案 1 :(得分:0)

我很惊讶这个程序有效。您已创建阻塞套接字,除非您正在使用非POSIX兼容的操作系统。接受电话应该从未返回。如果接受返回,则表示您的服务器套接字无法进入等待模式。因此,无论你看到什么,最有可能是因为错误。

SO_NONBLOCK是可用于创建非阻塞套接字的套接字选项。

由于您对客户端和服务器使用相同的例程,因此应在套接字循环中使用select。