Отправить запрос CGI из программы C ++? - PullRequest
0 голосов
/ 18 августа 2011

В настоящее время я работаю над интеграцией прототипа продукта, который я сделал, в большую программу. В прототипе я создал HTTP-сервер на микроконтроллере, а затем написал HTML-код для вызова функций .cgi на веб-сервере. Это было для того, чтобы я мог управлять вводом / выводом на микроконтроллере через Ethernet.

Мой HTML кажется очень простым, чтобы вызвать функцию cgi на микроконтроллере, я сделал кнопки со следующим синтаксисом:

<script type="text/javascript">
function my_confirm(a){
  var r=confirm("Are you sure you'd like to run "+a+"?");
  if (r==true)  
    location.href = a;
}
</script>
<button type = "button" onclick=" my_confirm('started.cgi')" >Started</button>

Кроме того, если бы я набрал «169.254.129.12/started.cgi» в веб-браузере, микроконтроллер отреагировал бы соответствующим образом. Теперь, когда прототип завершен досрочно, моей новой задачей является интеграция моих элементов управления в программу C ++ / CLI. ОТЛИЧНЫЙ. Я никогда не писал на C ++ ...

Вместо того, чтобы заново выполнять всю работу с бэкэндом, я хотел бы добавить меню для отправки похожих запросов. За последние 4-5 дней я получил меню в VS2005 и имел ограниченный успех, с кодом ниже:

int sendHttpRequestAndRespond(System::Uri^ url){
    if(url->Scheme == System::Uri::UriSchemeHttp){
        HttpWebRequest^ request = dynamic_cast<HttpWebRequest^>(WebRequest::Create(url));
        request->Method = System::Net::WebRequestMethods::Http::Get;
        return 0;
    }
    //HttpWebResponse^ response = dynamic_cast<HttpWebResponse^> (request->GetResponse());
    //RequestState^ state = gcnew RequestState();
    //state->request = request;
    //try{
    //  IAsyncResult^ response = dynamic_cast<IAsyncResult^> (request->BeginGetResponse(gcnew AsyncCallback( responseReceived),state));
    //}
    //catch(WebException^ e){}
    else
        return -1;
}

С кодом, написанным, как показано выше (с комментариями), управление вводом / выводом микроконтроллера не работает должным образом. Как ни странно, если я добавлю строку HttpWebResponse, то все (иногда) идет нормально, а в других случаях ничего не происходит. И наконец, если я использую AsyncResponse, все будет похоже на использование части HttpWebResponse.

Теперь я подумал / понял, что простое введение запроса через метод GET, который я использую в приведенном выше коде, может инициировать управление вводом / выводом на микроконтроллере, но, похоже, ответ также играет роль в нем. .

У кого-нибудь из вас есть лучший путь для этого? На данный момент я очень смущен / расстроен и открыт для любых советов! Спасибо,

РЕДАКТИРОВАТЬ 1: ОБНОВЛЕННЫЙ КОД:

int sendHttpRequestAndRespond(System::Uri^ url){
    if(url->Scheme == System::Uri::UriSchemeHttp){
        HttpWebRequest^ request = dynamic_cast<HttpWebRequest^>(WebRequest::Create(url));
        request->Method = System::Net::WebRequestMethods::Http::Get;
        RequestState^ state = gcnew RequestState();
        state->request = request;
        try{
                IAsyncResult^ response = dynamic_cast<IAsyncResult^> (request->BeginGetResponse(gcnew AsyncCallback( responseReceived),state));
            }
        catch(WebException^ e){}
        return 0;
    }

С этим кодом я вхожу в свою функцию обратного вызова (responseReceived) первые два раза, когда я вызываю эту функцию, но никогда в 3-й или последующий раз. Я проверяю это с http://www.facebook.com,, так как это похоже на мой CGI-вызов, но только первые два раза. Спасибо,

РЕДАКТИРОВАТЬ 2: Разрешение и новые проблемы! Хорошо, я поняла, что моя проблема в основном из-за того, что запросы не заканчивались. В функции callBack я не заканчивал запрос, а протокол HTTP имеет ограничение на 2 соединения / ip, что делает первые два вызова работающими, но будущие - нет.

Теперь моя новая проблема заключается в том, что при вызове asyc, который я использую, сначала выполняется синхронное разрешение DNS. Поскольку я отправляю эти команды на встроенный компьютер с IP-адресом, между ними нет DNS, и функциональные блоки уже давно. Как только мой компьютер понимает, что произошла ошибка разрешения DNS, он запускает запрос любым способом, и это работает! Последующие запросы работают мгновенно, так как есть кэш, который запоминает сбой.

Так что я прохожу около 99% пути, но мне нужно как-то исправить эту первую блокировку. Мои текущие идеи:

Как-то отключить разрешение днс перед запросом

Сократить время ожидания разрешения DNS с 60+ секунд до 1 секунды

обманите мой компьютер / компьютер, на котором программа работает, думая, что http://169.254.129.12 имеет IP-адрес 169.254.129.12 (файл локального хоста ??)

Я не уверен, как это сделать, или есть идеи получше ?? 1042 *

Спасибо,

Есть идеи получше?

1 Ответ

0 голосов
/ 18 августа 2011

Я не очень знаком с классом HttpWebRequest и связанными с ним классами, но, насколько я понимаю, запрос не будет отправлен на сервер, пока вы либо (а) не отправите его явно, записав в поток запроса, либо (б) получить ответ, вызвав GetResponse.Поэтому для начала я думаю, что вам нужно раскомментировать все эти вещи.

Интересно, почему вы возвращаетесь в строку 5, прежде чем делать что-либо с запросом.Я знаю, что этот код находится в стадии разработки.Но, конечно же, вы не хотите возвращаться, прежде чем что-то делать?

И, наконец, вы используете асинхронную связь, что, вероятно, является дополнительной сложностью, без которой вы можете обойтись прямо сейчас.Я предлагаю вам сделать все синхронно сначала, чтобы оно заработало, а затем переключиться на асинхронный режим, если вам действительно нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...