2016-07-26 116 views
0

我在同一台PC(在Windows 10上)有一个C++客户端和golang服务器,并且我希望客户端向服务器发送POST请求。我想发送的请求是/ test。这两个项目编译并运行良好,但请求不是由客户端处理,即使服务器正显示出在Windows上使用C++在本地发送POST请求

"HTTP-GA-SERVER: POST Successfully sent" 

这里是C++代码:

#include <winsock2.h> 
#include "ga-http-post.h" 

int sendPostToMushroom(HttpRequestType req, void* metrics) 
{ 
    WSADATA wsaData; 
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { 
     std::cout << "WSAStartup failed." << std::endl; 
     return 1; 
    } 
    SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 

    SOCKADDR_IN SockAddr; 
    SockAddr.sin_port=htons(8080); 
    SockAddr.sin_family=AF_INET; 
    SockAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 

    std::cout << "HTTP-GA: Connecting..." << std::endl; 

    if (Socket < 0) { 
     std::cout << "HTTP-GA: Error creating socket: " << WSAGetLastError() << std::endl; 
     return 1; 
    } 

    if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0){ 
     std::cout << "HTTP-GA: Error connecting: " << WSAGetLastError() << std::endl; 
     return 1; 
    } 
    std::cout << "HTTP-GA: Connected to " << inet_ntoa(SockAddr.sin_addr) << std::endl; 

    char buffer[2048]; 
    strcpy(buffer,"POST /test HTTP/1.1\n"); 

    if (send(Socket,buffer, strlen(buffer),0) != strlen(buffer)) 
    { 
     std::cout << "HTTP-GA: Error sending:" << WSAGetLastError() << std::endl; 
     return 1; 
    } 
    closesocket(Socket); 
    WSACleanup(); 
    std::cout << "HTTP-GA: POST Successfully sent" << std::endl; 
    return 0; 
} 

而且golang代码:

func (a *Agent) runGaHTTPHandler() { 
    fmt.Println("HTTP : Init HTTP Server") 

    http.HandleFunc("/ready", a.handleServerReady) 
    http.HandleFunc("/unavailable", a.handleServerUnavailable) 
    http.HandleFunc("/connected", a.handleClientConnected) 
    http.HandleFunc("/disconnected", a.handleServerUnavailable) 
    http.HandleFunc("/MetricsCollected", a.handleMetrics) 
    http.HandleFunc("/test", a.handleTest) 

    fmt.Println("HTTP : Listen and serve") 
    log.Fatal(http.ListenAndServe(":8080", nil)) 
} 

func (a *Agent) handleTest(w http.ResponseWriter, r *http.Request) { 
    fmt.Print("HTTP : Test successful\n") 
} 

编辑:C++代码改变时,仍然没有工作

+0

‘我希望服务器POST请求发送到客户端。’ - 这是一个错字吗?你不想让C++客户端向Go服务器发送请求吗? (对不起,如果我误解)。你也说'服务器正在显示'HTTP-GA-SERVER:POST成功发送'' - 但是这个消息在C++ **客户端**代码中...... – dmitris

+0

@dmitris这是一个错字,我的日志消息是误导。对不起,我编辑了代码。 – tankyx

回答

1

埃德它
在客户端代码,试图改变: strcpy(buffer,"POST /test HTTP/1.1\n");strcpy(buffer,"POST /test HTTP/1.1\r\nHost: localhost\r\n\r\n");

HTTP/1.1需要Host HTTP报头的存在;在标题之后,应该有一个额外的换行符(\r\n)。当然,如果需要,将localhost更改为实际的主机名。

[关于围棋的HTTP服务器代码前面的答案]
handleTest功能,你需要写http.ResponseWriter w或使用其WriteHeaderWrite功能。目前您的代码中的fmt.Print很可能会在您启动Go服务器的终端中打印字符串,但不会将其发送到客户端。试试你的围棋程序以下(简体)版本:

package main 

import (
    "fmt" 
    "log" 
    "net/http" 
) 

func main() { 
    http.HandleFunc("/test", handleTest) 

    fmt.Println("HTTP : Listen and serve") 
    log.Fatal(http.ListenAndServe(":8080", nil)) 
} 

func handleTest(w http.ResponseWriter, r *http.Request) { 
    w.Write([]byte("HTTP : Test successful\n")) 
} 

当你开始转到服务器,客户端应该得到这样一个具有卷曲做了回应(你也可以通过用于测试的浏览器访问) :

 
$ curl http://localhost:8080/test 
HTTP : Test successful 

你可以看到ResponseHeaderWriteWriteHeader functiosn的描述为净/ HTTP包的文档中:https://golang.org/pkg/net/http/#ResponseWriter

+0

嗨! 感谢您的快速回答。实际上,我想在控制台中打印该消息,而不是将其发送给客户端。客户端发送的东西,并不等待任何答案:)我已尝试curl命令,并且它正确输出我想要的消息,所以问题来自c + +代码 – tankyx

+0

我看到 - 编辑答案建议发送一个在来自C++客户端的请求中有效的'Host' HTTP标头 – dmitris