2015-02-24 22 views
0

我有一個C客戶端和一個Java服務器(通過eclipse的Tomcat)。
1- C客戶端用於向Java服務器執行一個字符串的HTTP Post [出錯]
2-服務器有一個本地HTML表單頁面,用於保存接收到的任何字符串並將其寫入文件[Works fine;測試]從C客戶端到Java服務器的Http Post字符串給出錯誤400 Bad Request

我遇到的問題是我無法讓服務器成功接收並保存從客戶端的字符串發佈。服務器反應爲「錯誤400錯誤請求」。

但是,我能夠讓服務器保存通過html表單頁面手動輸入的任何字符串。

我只需要讓客戶端而不是我發佈到HTML表單頁面(除非有更好的方式讓客戶端發佈到服務器而不需要表單頁面)。

我不是網絡和套接字編程方面的專家。任何幫助是極大的讚賞。

這裏是Java服務器代碼:

<html> 
<body> 
    <form action="HelloForm" method="POST"> 
     Parameter: <input type="text" name="first_name"> 
        <br /> 
        <input type="submit" value="Submit" /> 
    </form> 
</body> 
</html> 
<? 

這裏是C客戶機代碼:

#include <stdio.h> /* printf, sprintf */ 
#include <stdlib.h> /* read, write, close */ 
#include <string.h> /* memcpy, memset */ 
#include <sys/socket.h> /* socket, connect */ 
#include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */ 
#include <netdb.h> /* struct hostent, gethostbyname */ 
#include <unistd.h> 

void error(const char *msg) { perror(msg); exit(0); } 

int main(int argc,char *argv[]) 
{ 
    /* first what are we going to send and where are we going to send it? */ 
    int portno =  8080; 
    char *host =  "192.168.1.65"; /* localhost: 127.0.0.1 or 192.168.1.65 */ 
    char *message_fmt = "POST /Parameter=%s&command=%s HTTP/1.1\n\n"; 

    struct hostent *server; 
    struct sockaddr_in serv_addr; 
    int sockfd, bytes, sent, received, total; 
    char message[1024],response[4096]; 

    if (argc < 3) { puts("Parameters: <apikey> <command>"); exit(0); } 



    /* fill in the parameters */ 
    sprintf(message,message_fmt,argv[1],argv[2]); 
    printf("Request:\n%s\n",message); 

    /* create the socket */ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) error("ERROR opening socket"); 

    /* lookup the ip address */ 
    server = gethostbyname(host); 
    printf("ip address: %s\n\n", host); 
    if (server == NULL) error("ERROR, no such host"); 

    /* fill in the structure */ 
    memset(&serv_addr,0,sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_port = htons(portno); 
    memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length); 

    /* connect the socket */ 
    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) 
     error("ERROR connecting"); 
    /* send the request */ 
printf("Sending request\n\n"); 
total = strlen(message); 
    sent = 0; 
    do { 
     //bytes = write(sockfd,a+sent,total-sent); 
     bytes = write(sockfd,message+sent,total-sent); 
     if (bytes < 0) 
      error("ERROR writing message to socket"); 
     if (bytes == 0) 
      break; 
     sent+=bytes; 
    } while (sent < total); //while (sent < 0); 
    printf("Post request sent \n"); 

    //receive the response 
    printf("Receiving response \n"); 
    memset(response,0,sizeof(response)); 
    total = sizeof(response)-1; 
    received = 0; 
    do { 
     bytes = read(sockfd,response-received,total-received); 
     if (bytes < 0) 
      error("ERROR reading response from socket"); 
     if (bytes == 0) 
      break; 
     received+=bytes; 
    } while(received < total); //while (received < 0); 
    printf("Response received\n"); 

    if (received == total) 
     error("ERROR storing complete response from socket"); 

    /* close the socket */ 
    close(sockfd); 

    /* process response */ 
    printf("\nServer Response:\n%s\n\n",response); 

    return 0; 
} 
服務器的

// Import required java libraries 
import java.io.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 
import java.io.IOException; 

// Extend HttpServlet class 
public class HelloForm extends HttpServlet { 

    private OutputStream ostream; 
// Method to handle GET method request. 
    public void doGet(HttpServletRequest request, 
        HttpServletResponse response) 
      throws ServletException, IOException 
    { 
     // Set response content type 
     response.setContentType("text/html"); 

     PrintWriter out = response.getWriter(); 
     String title = "Using GET Method to Read Form Data"; 
     String docType = 
     "<!doctype html public \"-//w3c//dtd html 4.0 " + 
     "transitional//en\">\n"; 
     out.println(docType + 
       "<html>\n" + 
       "<head><title>" + title + "</title></head>\n" + 
       "<body bgcolor=\"#f0f0f0\">\n" + 
       "<h1 align=\"center\">" + title + "</h1>\n" + 
       "<ul>\n" + 
       " <li><b>First Parameter</b>: " //Displayed on result page NOT html page 
       + request.getParameter("first_name") + "\n" + 
       " <li><b>Last Parameter</b>: " //Displayed on result page NOT html page 
       + request.getParameter("last_name") + "\n" + 
       "</ul>\n" + 
       "</body></html>"); 
     //printing result to console: 
     System.out.println(request.getParameter("first_name")); 
     System.out.printf("Parameter Entered: %s\n", request.getParameter("first_name")); 

    ////printing results to file: 
     { 

try(PrintWriter serveroutput = new PrintWriter(new BufferedWriter(new FileWriter("/home/salimramjean/Desktop/ServerOutput.txt",true)))) { 
    serveroutput.println(request.getParameter("first_name")); 

      } 

     }  
    } 
    // Method to handle POST method request. 
    public void doPost(HttpServletRequest request, 
        HttpServletResponse response) 
     throws ServletException, IOException { 
    doGet(request, response); 
    } 
} 

HTML表單頁面

這裏是web.xml中的我如何運行,編譯

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> 
    <display-name>FormServ</display-name> 
    <welcome-file-list> 
    <welcome-file>index.html</welcome-file> 
    <welcome-file>index.htm</welcome-file> 
    <welcome-file>index.jsp</welcome-file> 
    <welcome-file>default.html</welcome-file> 
    <welcome-file>default.htm</welcome-file> 
    <welcome-file>default.jsp</welcome-file> 
    </welcome-file-list> 

    <servlet> 
     <servlet-name>HelloForm</servlet-name> 
     <servlet-class>HelloForm</servlet-class> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>HelloForm</servlet-name> 
     <url-pattern>/HelloForm</url-pattern> 
    </servlet-mapping> 

</web-app> 

例子:
$ ./client IamSendingThisString提交在終端上顯示

結果:

Request: 
POST /Parameter=IamSendingThisString&command=submit HTTP/1.1 


ip address: 192.168.1.65 

Sending request 

Post request sent 
Receiving response 
Response received 

Server Response: 
HTTP/1.1 400 Bad Request 
Server: Apache-Coyote/1.1 
Transfer-Encoding: chunked 
Date: Tue, 24 Feb 2015 09:22:15 GMT 
Connection: close 

0 

正確的更改制作:

1- Edited POST header: 
char *message_fmt = "POST /FormServ/HelloForm HTTP/1.1\r\nHost: %s:%d\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\nfirst_name=%s&last_name=%s\r\n"; 

2- Added content type: 
char *contentType = "application/x-www-form-urlencoded"; 

3- Added Content length 
+0

不應該有'?'在第一個參數之前,即「POST /?Parameter = IamSendingThisString&command = submit HTTP/1.1」 – 2015-02-24 10:22:49

+0

我剛剛嘗試過,但它仍然給我與上面相同的結果。 – 2015-02-24 10:25:47

回答

1

你在這個線的問題: 「POST /參數=%s的&命令=%s的HTTP/1.1 \ n \ n」 個

我不知道究竟是什麼參數應發,但它至少包含2個錯誤:

1)沒有符號?在參數列表之前。應該是/?Parameter =%s & command =%s如果你的servlet部署在/中,而不是像/ index這樣的其他頁面。JSP

2)不與\ r \ n結束(與\ n \ n代替)

而且也許你應該發送頭內容長度,內容類型和額外的結束\ r \ n在結束或請求。

試圖找到一些工作套接字客戶端的例子和複製代碼。例如http://examples.javacodegeeks.com/core-java/net/socket/send-http-post-request-with-socket/

+0

我已經添加了\ r \ n和內容長度(上面已編輯),但現在我收到一個空白答覆:( – 2015-02-24 16:53:03

+1

@SlimR在web.xml中檢查請求映射,您的HelloServlet應該映射爲/並且web應用程序應該部署在ROOT,檢查服務器日誌和http訪問日誌,你真的打到正確的url嗎? – user1516873 2015-02-24 17:06:17

+0

我已經發布了我的web.xml上面。你認爲有任何需要改變嗎? – 2015-02-26 09:29:32

2

你的C代碼不發送有效的HTTP/1.1請求。標題中的每一行必須以CRLR(即「\ r \ n」)結尾,並且標題後面必須跟一個空行(僅限CRLF)。請參閱:http://tools.ietf.org/html/rfc2616#page-31

+0

謝謝托馬斯,加入\ r \ n已經擺脫了錯誤的請求,但是現在我得到一個空白的響應,即請求響應:*空白*,而不是以前的結果。 – 2015-02-24 16:52:21

相關問題