libCURL 라이브러리를 사용하여 HTTP POST 명령을 외부 장치로 보내고 있습니다. 두 가지 기본 명령이 있습니다. 첫 번째 장치는 장치에서 현재 콘텐츠를 지우도록 지시하고 두 번째 장치는 새 콘텐츠를 보냅니다. 두 가지 모두 동일한 POST 헤더 구조/주소를 사용하지만 "내용 보내기"명령을 수행하는 동안 데이터가 첨부된다는 유일한 차이점이 있습니다. 두 명령 모두 제대로 실행됩니다. 첫 번째 명령은 데이터를 지우고 두 번째 명령은 보냅니다. 그러나 프로그램을 드물게 (시간의 30 % 정도) "내용 보내기"명령 후 충돌이 발생합니다. 오류가 없습니다. 전에 말했듯이 데이터가 전송 될 때까지 충돌이 발생하지 않으며 항상 발생하지는 않으므로 특히주의해야합니다.내용에 Libcurl이 자주 충돌하지 않습니다. POST
코드는 아래에 첨부되어 있습니다. 프로그램이 'curl_easy_perform (curl)'액션을 벗어나기 위해 필요한 콘텐츠를 보낸 후 실종 된 것이 있습니까? 나는 아직도이 유형의 일로 상당히 경험이 없으며 가질 수있는 조언을 공개합니다.
int fnSendContent(BMP* pbmpContent)
{
using namespace std;
int Error = 0;
CURL* curl;
CURLcode res;
struct curl_slist *headerlist=NULL;
static const char buf[] = "aaaaaaaaa";
CString str;
string sURL;
long lTimeout = 10;
//Pass image into char array so that it can be sent to VIP
ifstream fsContent;
fsContent.open("MyImage.bmp",ios_base::binary);
fsContent.seekg(0,ios::end);
long lBMP_size = fsContent.tellg();
fsContent.seekg(0,ios::beg);
char* pcContent = new char[lBMP_size];
for (int i = 0; i < lBMP_size; i++)
pcContent[i] = 'F';
bool bit = fsContent.eof();
fsContent.read(pcContent,lBMP_size);
fsContent.close();
string Content_Length = "Content-Length: " + to_string((long long)lBMP_size);
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
//Build header
headerlist = curl_slist_append(headerlist, buf);
headerlist = curl_slist_append(headerlist, "Authorization: MyAuth);
headerlist = curl_slist_append(headerlist, "Accept: MyAccept");
headerlist = curl_slist_append(headerlist, "Content-Type: image/bmp");
headerlist = curl_slist_append(headerlist, "Connection: keep-alive");
headerlist = curl_slist_append(headerlist, Content_Length.c_str());
headerlist = curl_slist_append(headerlist, "Expect: "); //Supress "Expect:" heading
//Set URL to receive POST
curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
curl_easy_setopt(curl,CURLOPT_POST, true);
curl_easy_setopt(curl, CURLOPT_HEADER, true);
curl_easy_setopt(curl,CURLOPT_TIMEOUT, lTimeout);
curl_easy_setopt(curl, CURLOPT_URL, "http://URL:Port/Command");
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, lBMP_size);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pcContent);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
//Send
res = curl_easy_perform(curl); //Crash occurs on send
CString str2(curl_easy_strerror(res));//Get Error Explanation
if(res != CURLE_OK)
{
str2.Format(_T("curl_easy_perform() failed: %s [%d]"), str2,res);
DebugOut->AddString(str2);
Error = E_SHOW_IMG;
}
curl_easy_cleanup(curl);
curl_global_cleanup();
curl_slist_free_all(headerlist);
delete[] pcContent;
return Error;
}
편집 :
내가 헤더와 "curl_easy_perform (컬)"를 사용하여 데이터를 전송 한 후 충돌이 발생하지만 이전에 프로그램의 나머지 부분에 성공적으로 돌아 가기 : 다니엘은 더 많은 정보를 요구했다. 저는 VC++로 코딩 중이며 일반 "오류가 발생했습니다"만 수신합니다. 데이터가 수신 된 후에 오류가 발생한다는 사실은 내가 명령을 제대로 종료하지 않는다고 생각하게 만듭니다. 충돌하는 POST 명령의 WireShark 출력이 아래에 나와 있습니다.
Source Destination Protocol Length Info
------------------------------------------------------------
|MySourceIP | MyDestIP | HTTP | 16438 | POST /Command|
------------------------------------------------------------
POST /Command HTTP/1.1..Host: URL:Port..Authorization: My Auth..Content-Type:
image/bmp..Accept: MyAccept..Connection: keep-alive..Content-Length: 61
494....BM6.......6...(..........
[Followed by 61,494 bytes of data ending in null]
CURLOPT_POSTFIELDSIZE_LARGE 옵션은 'curl_off_t'인수를 사용하지만 'long'을 전달합니다. 아마 문제는 아니지만 여전히 오류 일 것입니다. "충돌"에 대한 자세한 내용을 알려주고 자세한 로그를 표시 할 수 있습니까? –
잘하면 나는 그것을 조금 분명히했다. 어려움은 "좋음"(non-crashing) POST와 "나쁜"POST가 어느 정도 같아 보입니다. 그러나 WireShark가 헤더와 파일의 총 길이 (~ 16438)보다 프레임 길이가 400-500 인 "양호한"명령을 볼 수 있음을 알았습니다. –
죄송합니다. 귀하의 코드에 어떤 문제가 보이지 않습니다. –