2016-08-27 3 views
-2

localhost에서 실행중인 Apache로 데이터를 보내려고합니다. 데이터는 JSON 형식으로 올바르게 형성,하지만 난 libcurl에를 사용하여 데이터를 보낼 때 PHP 웹 서버에 나는 그것은 임의의 문자를 반환C++ libcurl이 잘못된 데이터를 보내고 있습니다.

echo file_get_contents("php://input"); 

를 사용하여 문자열을 반향되고,이 서버가

을 에코 데이터입니다
`é ²²²²▌▌▌▌4Ég\▌ îHGáF 

그리고 C++에서는 json을 에코 할 때 올바르게 인쇄됩니다.

Request.C++

void Request::execute() { 
auto curl = curl_easy_init(); 

if (curl) { 
    curl_easy_setopt(curl, CURLOPT_URL, mUrl); 
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); 
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "RoBot/ Version 1"); 
    curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L); 
    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1); 

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write); 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &mResponse); 
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &mHeaders); 
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &mResponseCode); 

    if (!mData.empty()) { 
     curl_easy_setopt(curl, CURLOPT_POST, true); 
     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, mData); 
     curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, mData.size()); 
    } 

    if (mHeadersData) { 
     curl_easy_setopt(curl, CURLOPT_HEADER, true); 
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, mHeadersData); 
    } 

    curl_easy_perform(curl); 
    curl_easy_cleanup(curl); 
    curl_slist_free_all(mHeadersData); 
    curl = nullptr; 
} 

그리고 내가 그것을 실행하고 방법이있다.

json data; 
data["username"] = username; 
data["password"] = password; 
std::cout << data.dump() << std::endl; 

//Request* request = new Request("https://www.roblox.com/MobileAPI/Login"); 
Request* request = new Request("http://localhost:8080/Projects/"); 
request->setPostData(data.dump()); 
//request->addHeader("Content-Type: application/json"); 
request->execute(); 

std::cout << request->getResponse() << std::endl; 
std::cout << request->getHeaders() << std::endl; 

이 콘솔

Username: id 
Password: kf 
{"password":"kf","username":"id"} 
`é ²²²²▌▌▌▌4Ég\▌ îHGáF 
HTTP/1.1 200 OK 
Date: Sat, 27 Aug 2016 09:15:07 GMT 
Server: Apache/2.4.6 (Win32) PHP/5.4.17 
X-Powered-By: PHP/5.4.17 
Content-Length: 36 
Content-Type: text/html 

어떤 아이디어 왜 무슨 인쇄되는입니까?

[EDITED]

는 쓰기 기능은 내가 지금

void Request::setPostData(std::string data) { 
mData = data; 
} 

[수정 됨 2]

를 그래서 다음과 같이하고있는 데이터를 설정하고

size_t write(void *ptr, size_t size, size_t nmemb, std::string* data) { 
data->append((char*)ptr, size * nmemb); 
return size * nmemb; 
} 

아래로 보여 문제를 알고, 명백하게 libcurl은 char * 만 받아 들인다. 그리고 나는 std :: string을 보내고있다. 내 json 라이브러리가 json 객체를 std :: string으로 변환 한 이후로이 문제를 해결할 수있는 방법이 있습니까?

+0

C- 스타일 문자열이 끝나지 않은 것 같습니다. 'setPostData'와'write' 함수를 보여주십시오. –

+1

이것은 많은 정보가 누락되었습니다. 'write()'(libc'write()'는 curl의 write 함수와 완전히 다른 서명을 가지고 있기 때문에) 무엇입니까? 'mData' 란 무엇입니까? 'curl_easy_setopt()'는 varargs 함수이므로 타입 변환이 필수적으로 보인다. – dhke

+0

좋아요, 요청에 따라 더 많은 정보를 업데이트했습니다. – Kurieita

답변

-2

다음 요청 헤더를 설정해보십시오.

수락 : 텍스트/
일반 수락 - 문자셋 : UTF-8
수락 - 인코딩 : identity

(만들뿐만 아니라 아마도 컨텐츠 형이 확인 서버가 올바른 방법을 보낼 것을 해석)

ref

+0

웹 서버가 utf16 및/또는 압축 형식으로 응답을 전달하고 클라이언트 라이브러리가 raw 형식으로 응답을 제공하면 이러한 헤더가 제공 될 수 있습니다. 나는 그것을 해결책이라고 제안하지 않았으며, 최선의 노력이 예상/실제 사이의 인코딩 불일치를 피하기 위해 행해지는 것을 의미합니다. ("아마도 시도 ..."참조) –

+0

@DanielStenberg 현재 제안, 쓰기 기능 및 m_data에 관한 두 가지 설명을 사용할 수 없습니다 (그리고 그것은 나를 위해 취침 시간이었다). 왜 코멘트 대신 답변으로 게시하기로 결정했는지 - 댓글에 텍스트 형식이 제한되어 있습니다. –

+0

@Ahmad 죄송 합니다만, 나는 단지 가설을 전진 시켰고, 내가 제안한 것이 명백히 진실인지는 확실하지 않았습니다. 따라서 "아마도 당신이해야 할 것"과 "아마도 콘텐츠 유형"대신에 "아마도 무언가를하려고 노력합니다". –

2

이 줄은 잘못된 것입니다 :

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, mData); 
libcurl에서 문서 당

는 :

CURLOPT_POSTFIELDS explained

는 HTTP의 POST 작업에 보낼 전체 데이터를 가리키는 매개 변수로 *는 문자를 전달합니다. 데이터를 서버가 수신하는 방식으로 형식화되어 있는지 확인해야합니다. libcurl은 어떤 식 으로든 그것을 변환하거나 인코딩하지 않습니다. 예를 들어 웹 서버는이 데이터가 URL로 인코딩되었다고 가정 할 수 있습니다.

가리키는 데이터는 라이브러리에서 복사하지 않습니다. 따라서 연결된 전송이이 끝날 때까지 호출 응용 프로그램에서 보존해야합니다. CURLOPT_COPYPOSTFIELDS 옵션을 설정하면이 동작을 변경할 수 있습니다 (libcurl이 데이터를 복사합니다).

당신은 문자 데이터에 대한 char* 포인터로 시작하는 std::string의 내부 구현에 의존하고 있지만이 보장되지 않습니다. 라인이 대신과 같아야합니다 : 당신은 문자 데이터에 char* 포인터를 얻을 보장

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, mData.c_str()); 

합니다. 포인터는 std::string이 수정되거나 파괴 될 때까지 유효합니다.

+0

와우 나는 그것을 시도하고 그것이 작동하지 않았다는 것을 맹세한다. 명백하게 그것은 지금 일했다. 고마워. – Kurieita

관련 문제