2011-04-29 60 views
1

我是c socket編程和c本身的新手。我寫了一小段代碼,它從另一個互聯網套接字讀取原始輸入並將數據發佈到網絡服務器。接收到的數據始終是數字。然而問題似乎是http post請求只發生一次,而不是在循環中運行,程序終止。C Socket編程:HTTP請求不能連續工作

下面是代碼示例

#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; 
} 
+0

診斷詳情,請。你在代碼中有很多很好的'perror()';當然你不會介意與我們分享程序停止的原因,是嗎? – atzz 2011-04-29 11:55:23

回答

3

我沒有做過socket編程多年,所以請多多包涵。你需要連接,處理,然後斷開連接嗎?這是第一個想到讀你的代碼。

+0

謝謝你的工作.. – 2011-04-29 13:13:11

+0

由於HTTP1.1在服務請求後關閉連接,連接必須重新啓動。 – 2011-04-29 13:14:16

0

我很驚訝這個程序的作品。您已經創建了阻塞套接字,除非您正在使用非POSIX兼容的操作系統。接受電話應該從未返回。如果accept返回,則意味着您的服務器套接字無法進入等待模式。因此無論你看到什麼都很可能是因爲錯誤。

SO_NONBLOCK是您可以用來創建非阻塞套接字的套接字選項。

由於您對客戶端和服務器都使用相同的例程,因此應該在套接字循環中使用select。

+0

你確定嗎?我的理解是'accept'會阻塞,直到客戶端連接,然後程序將繼續連接到服務器。我不確定這是作者的縮影,但並不一定是錯誤的。 – atzz 2011-04-29 12:58:15