从 C 客户端到 Java 服务器的 Http Post 字符串给出错误 400 Bad Request

Http Post string from C client to Java server gives error 400 Bad Request

我有一个 C 客户端和一个 Java 服务器(Tomcat 通过 eclipse)。
1- C 客户端旨在对 Java 服务器执行字符串的 HTTP Post [给出错误].
2- 服务器有一个本地主机 HTML 表单页面,用于保存它收到的任何字符串 posted 并将其写入文件 [工作正常;已测试]

我遇到的问题是我无法让服务器成功接收并保存来自客户端的字符串 post。服务器以 [​​=63=] 代替响应。

但是,我可以让服务器保存通过 html 表单页面手动输入的任何字符串。

我只需要让客户端代替我,post到html表单页面(除非有更好的方法让客户端post到服务器无需表单页面)。

我不是网络和套接字编程方面的专家。非常感谢任何帮助。

这是Java服务器代码:

// 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 服务器表单页面:

    <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;
}

这里是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

您的 C 代码未发送有效的 HTTP/1.1 请求。 header 中的每一行都必须以 CRLF 结尾(即“\r\n”),并且 header 后面必须跟一个空行(只有 CRLF)。参见:https://www.rfc-editor.org/rfc/rfc2616#page-31

你在这一行的问题:"POST /Parameter=%s&command=%s HTTP/1.1\n\n"

我不知道应该发送什么参数,但它包含至少 2 个错误:

1) 没有符号?在参数列表之前。如果您的 servlet 部署在 /,应该是 /?Parameter=%s&command=%s,而不是像 /index.jsp

这样的其他页面

2) 不以 \r\n 结尾(而是以 \n\n 结尾)

也许你应该在最后或请求中发送 headers Content-length、Content-type 和额外的 \r\n。

尝试找到一些有效的套接字客户端示例并复制代码。例如http://examples.javacodegeeks.com/core-java/net/socket/send-http-post-request-with-socket/