在 Windows 上用 C++ 在本地发送 POST 请求
Sending a POST request locally in C++ on Windows
我在同一台电脑上有一个 c++ 客户端和一个 golang 服务器(在 windows 10),我希望客户端向服务器发送 POST 请求。我要发送的请求是 /test 请求。两个项目都可以编译 运行,但是客户端不处理请求,即使服务器正在显示
"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++ 代码已更改,仍然无法正常工作
编辑
在客户端代码中,尝试更改:
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 header;在 header 之后,应该有一个额外的换行符 (\r\n
)。当然,如果需要,请将 localhost
更改为实际的主机名。
[关于 Go http 服务器代码的先前回答]
在handleTest
函数中,需要写入http.ResponseWriterw
或者使用其WriteHeader
和Write
函数。当前代码中的 fmt.Print
很可能会在启动 Go 服务器的终端中打印字符串,但不会将其发送到客户端。试试你的 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"))
}
当你启动 Go 服务器时,客户端应该会得到像这样用 curl 完成的响应(你也可以通过浏览器访问它进行测试):
$ curl http://localhost:8080/test
HTTP : Test successful
您可以在 net/http 包的文档中查看 ResponseHeader
的 Write
和 WriteHeader
功能的描述:https://golang.org/pkg/net/http/#ResponseWriter
我在同一台电脑上有一个 c++ 客户端和一个 golang 服务器(在 windows 10),我希望客户端向服务器发送 POST 请求。我要发送的请求是 /test 请求。两个项目都可以编译 运行,但是客户端不处理请求,即使服务器正在显示
"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++ 代码已更改,仍然无法正常工作
编辑
在客户端代码中,尝试更改:
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 header;在 header 之后,应该有一个额外的换行符 (\r\n
)。当然,如果需要,请将 localhost
更改为实际的主机名。
[关于 Go http 服务器代码的先前回答]
在handleTest
函数中,需要写入http.ResponseWriterw
或者使用其WriteHeader
和Write
函数。当前代码中的 fmt.Print
很可能会在启动 Go 服务器的终端中打印字符串,但不会将其发送到客户端。试试你的 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"))
}
当你启动 Go 服务器时,客户端应该会得到像这样用 curl 完成的响应(你也可以通过浏览器访问它进行测试):
$ curl http://localhost:8080/test HTTP : Test successful
您可以在 net/http 包的文档中查看 ResponseHeader
的 Write
和 WriteHeader
功能的描述:https://golang.org/pkg/net/http/#ResponseWriter