發送 socket 資料前,使用 _write 方法 進行 socket 通訊檢查的bug
version: gsoap_2.7.13
operate system: windowsxp
describe:
I want to send the http request mulitie times by the same socket. and I coded as follow:
for ( size_t retrytimes = 0; retrytimes < 3; retrytimes ++ )
{
// whenever connected; send the http request;
if(
soap_end_send( dom.soap )
)
{
// if failed, try to create the socket session;
soap_connect( dom.soap, url , NULL ) ;
}
// once send success, break the loop;
else
that is {
break;
}
}
the problam is : wheath the connect is estabilsh or not, soap_end_send() always success.
I find that is because some code valide the socket connnect as follow:
in soapstd2.cpp::fsend() 中,
#ifdef WIN32
nwritten = _write(soap->sendfd, s, (unsigned int)n);
#else
nwritten = write(soap->sendfd, s, (unsigned int)n);
#endif
the write is just a normaly IS function and It can't sure weather the fild handle is a socket handle . so , if I just open a normal file, it is just return success.
I think send() is more 合適的。
2\容錯性:
such tag:
<div><ul><span>hello!</span>
</div>
soap_element_end_in(struct soap *soap, const char *tag)
if (tag && (soap->mode & SOAP_XML_STRICT))
{ soap_pop_namespace(soap);
if (soap_match_tag(soap, soap->tag, tag))
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n"));
// //不匹配的情況下,手動地添加結束串使之匹配
soap->bufidx -= strlen(soap->tag);
soap->bufidx = offset;
soap->ahead = SOAP_TT;
strncpy( soap->tag, tag, strlen( tag ) );
標籤中如果第一個字為漢字,則出現亂碼的問題。
如下的一個 utf-8 編碼的 串:
soap_get
<ul>
<li>公 司:先原房產佳林店</li>
<li>地 址:上海市浦東新區佳林路134號 </li>
</ul>
解析後儲存的結果是
<ul>
<li>l 司:立好信房屋</li>
<li>0 址:常德路1041號-1043號</li>
</ul>
“公”和“地”成為亂碼。這是 gosp 解析 xml 時的演算法缺陷。
在函數 soap_wchar soap_get(struct soap *soap) 中,讀取一個字元的演算法是:
如果 gsoap->ahead 中有一個字元,則返回這個字元。否則,從 gsoap->buf 中取一個字元, gsoap->bufidx++.
gsoap->aHead 的值來源於 soap_peek_element(),其邏輯是:
取到標籤 <li> 時,讀一個utf-8字。如果不是<,則判定是標籤的<li> 的 data(而不是子結點)。這就就需要把讀到的utf-8 退回去。
這裡不是退回 gsoap->bufidx--, 而是把這個值儲存在 gosp->ahead 中。而這裡 gsoap->ahead 儲存的是字元的 unicode 編碼。
if (c != SOAP_LT)
{ *soap->tag = '\0';
if ((int)c == EOF)
return soap->error = SOAP_EOF;
soap_unget(soap, c);
3、抽象的層次
gosp dom 有兩種 基本 對象:node 和 attribute 。每個對象有兩個屬性: name和 value。規則簡單。便於使用。但如果有以下的 html內容:
<div>
大海是<span>你</span>的故鄉
<div>
則 gosp 認為 大海是<span>你</span>的故鄉 是一個 value 屬性。而不會將 <span> 解析為一個結點。
xmlspy 比 gsoap 提供了更高層次的抽象。xml 中 node 是抽象的 dom 樹,而value 代表真正的值-- 這個值可能是 tag、也可能是 value,也可能是 在 xmpspy 中, 上面的 html 語句解析為
<div>
大海是
<span>
你
</span>
的故鄉
<div>
即一個div node 中有三個子 node。