uIPのイベント
uIPで簡単なHTTPクライアントを書いてみる。
大げさなものではなくGETしてそれを画面に出力するだけ。
まずはuIPのドキュメント通りに、各状態に合わせたハンドラを呼んでやる
void NetServer::DoEvent()
{
if (uip_aborted())
{
AbortedHandler();
}
if (uip_timedout())
{
TimeoutHandler();
}
if (uip_closed())
{
ClosedHandler();
}
if (uip_connected())
{
ConnectedHandler();
}
if (uip_acked())
{
AckedHandler();
}
if (uip_newdata())
{
NewDataHandler();
}
if (uip_rexmit() || uip_newdata() || uip_acked() || uip_acked() || uip_connected() || uip_poll())
{
SendDataHandler();
}
次にそれぞれのハンドラを定義してやります。
今回は実験なので、効率とか誰がメモリ解放するのかとか、エラーのときは?とかは一切考えていません。
void NetServer::ConnectedHandler()
{
printf("%s\n", __FUNCTION__);
struct server_state* s = (struct server_state *)uip_conn->appstate;
const char* message = "GET /file HTTP/1.0\r\nServer:192.168.100.2\r\n\r\n";
s->message = new char[strlen(message) + 1];
strcpy(s->message, message);
s->length = strlen(message) + 1;
}
void NetServer::AckedHandler()
{
printf("%s\n", __FUNCTION__);
struct server_state* s = (struct server_state *)uip_conn->appstate;
s->length -= uip_conn->len;
s->message += uip_conn->len;
if(s->length == 0)
{
printf("send done\n");
}
}
void NetServer::NewDataHandler()
{
printf("%s\n", __FUNCTION__);
for (dword i = 0; i < GetDataLength(); i++)
{
printf("%c", (char)uip_appdata[i]);
}
}
void NetServer::SendDataHandler()
{
printf("%s\n", __FUNCTION__);
struct server_state* s = (struct server_state *)uip_conn->appstate;
if (s->length != 0)
{
uip_send((volatile u8_t*)s->message, s->length);
}
}
フローとしては
1. 接続が完了すると ConnectedHandlerが呼ばれる
2. GETを発行するために、GET文字列と長さを格納
3. 送信
4. ackedが返ってきてまだ未送信分がある場合や、再送の必要があれば再送信します。
5.uip_newdata()が1だったらデータが返ってきています。
これを踏まえたうえで次のエントリーへ。