2014-01-14 23 views
0

這是關於一個只有ANSI C標準庫的嵌入式系統的soap客戶端的實現測試。從套接字讀取響應時,我得到了我之前寫的內容

將我的HTTP POST請求發送到服務器後,我試圖在response上保存SOAP XML文檔。但是當我打印我得到的響應時,除了整個XML文檔之外,它還附加了寫在套接字上的最後223個字節。

由於docbuff_size = 1024response以883個字符結尾,似乎並不是內存重疊問題。我雖然UTF-8編碼可能是一個問題,但我嘗試了不同的尺寸docbuff_sizebuffer_size,我總是得到相同的行爲。

如果我在標準輸出上使用fputs編寫我的buffer,那麼這些尾隨223個字節將不會顯示。我從buffer的內容構建responsestrncpy。我認爲這個問題隱藏在這兩個函數的不同行爲上。

這是我的代碼消化版本

... 

int n; 
char limiter[] = "\r\n\r\n"; 
bool first = true; 
bool limiter_found = false; 
char *pDocument = NULL; 
char *pTmp = NULL; 
unsigned int pDoc_len = 0; 
char buffer[buffer_size] = {0}; 
char midbuff[10] = {0}; 
char response_code[4] = {0}; 
bzero(tmp, sizeof(tmp)); 

char *response; 
response = malloc(docbuff_size); 
bzero(response, sizeof(response)); 
bTotal = 0; 
while ((n = read(serverSocket, buffer, sizeof(buffer)-1)) > 0) 
{ 

    buffer[n] = '\0'; 

    ... 

    // Case: limiter found in last iteration, then copy this buffer entirely 
    if(pDocument != NULL && (bTotal+strlen(buffer)) < docbuff_size){ 
     strncpy(response+bTotal, buffer, strlen(buffer)); 
     bTotal += strlen(buffer); 
    } 

    limiter_found = false; 
    if(pTmp = strstr(buffer, limiter)){ 
     pDocument = pTmp+4; 
     limiter_found = true; 
    } else if (!first && (pTmp = strstr(midbuff, limiter))){ 
     // Take out 3 from the tail offset, add 4 from limiter length = 1 
     pDocument = buffer + (pTmp - midbuff) + 1; 
     limiter_found = true; 
    } 

    if(limiter_found){ 
     strncpy(response, pDocument, strlen(pDocument)); 
     bTotal += strlen(pDocument); 
    } 

    if(fputs(buffer, stdout) == EOF) 
    { 
     printf("\n Error : Fputs error\n"); 
    } 
} 

if(response[0] != 0){ 
    printf("\n\nXML Document: \n" 
     "*************************************\n" 
     "%s\n" 
     "*************************************\n", response); 
} 

if(n < 0) 
{ 
    printf("\n Read error \n"); 
} 

if(response){ 
    free(response); 
    response = NULL; 
} 

這是輸出

REQUEST SENT: 
POST /xxxx/index.php HTTP/1.0 
Host: testzzzzz.dev 
User-agent: Blahblah 
Content-type: text/xml; charset="iso-8859-1" 
Content-length: 677 
SOAPAction: "http://testzzzzz.dev/xxxx/index.php/ActionXXXX" 

<?xml version="1.0" encoding="iso-8859-1"?><SOAP-ENV:Envelope SOAP- ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema"><SOAP-ENV:Body><ns1:ActionXXXX xmlns:ns1="http://testzzzzz.com/xxxx/nusoap" SOAP-ENC:root="1"><v1 xsi:type="xsd:string">Loremipsumdolorsitamet,consecteturadipisicingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitati</v1></ns1:ActionXXXX></SOAP-ENV:Body></SOAP-ENV:Envelope> 

HTTP RESPONSE (written by fputs): 
HTTP/1.1 200 OK 
Date: Tue, 14 Jan 2014 18:11:39 GMT 
Server: Apache/2.2.22 (Ubuntu) 
X-Powered-By: PHP/5.4.9-4ubuntu2.4 
X-SOAP-Server: DesiteG/0.9.5 (1.123) 
Content-Length: 660 
Vary: Accept-Encoding 
Connection: close 
Content-Type: text/xml; charset=UTF-8 

<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:ActionXXXXResponse xmlns:ns1="http://testzzzzz.com/xxxx/nusoap"><return xsi:type="xsd:string">ResponseStringblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblaResponseString</return></ns1:ActionXXXXResponse></SOAP-ENV:Body></SOAP-ENV:Envelope> 

XML Document (build by strncpy): 
************************************* 
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:ActionXXXXResponse xmlns:ns1="http://testzzzzz.com/xxxx/nusoap"><return xsi:type="xsd:string">ResponseStringblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblaResponseString</return></ns1:ActionXXXXResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>type="xsd:string">Loremipsumdolorsitamet,consecteturadipisicingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitati</v1></ns1:ActionXXXX></SOAP-ENV:Body></SOAP-ENV:Envelope> 
************************************* 

的摘錄如果滾動到左邊你可以看到什麼樣的fputs之間的差異也從什麼strncpy構建。最後兩次迭代(緩衝區獲得兩次使用)。 似乎read在最後一次迭代放置一些額外的數據緩衝區fputs正確忽略,但strncpy不會。

----編輯(解決,但我不知道爲什麼)----使用的strcpy,而不是strncpy()函數的

問題解決了。 看來strlen(buffer)忽略了之前編寫的buffer[n] = '\0'

strncpy(dest, src, strlen(src));strcpy(dest, src);不一樣嗎?

我想留下這個問題,直到解釋清楚的原因。

+1

您可能想使用調試器來了解發生了什麼。對於gcc使用選項'-g'編譯符號,然後使用'gdb --args程序名arg1 arg2 ... argn'運行程序。 – alk

+1

注視着代碼:'bzero(response,sizeof(response));'看起來很奇怪,如果'response'真的被聲明爲'char *'。 –

+1

我將使用一個野指針,在你沒有提供的代碼中的某處。如果這個猜測結果是正確的,那麼它不是真正的「解決」,更有趣的時刻等待着你... –

回答

0

正如@Ron Burk bzero(response, sizeof(response));所說的是錯誤的。

改爲ANSI C標準calloc

response = calloc(docbuff_size, sizeof(char));

解決了strncpy()函數的問題,雖然我將使用的strcpy以提高可讀性。

我認爲它發生的是response被分配在我寫請求的變量的頂部,然後它沒有被完全歸零,並且因爲strncpy不會像strcpy那樣添加最終的\0然後response將成爲新舊數據的混合。

沒有必要使用calloc,但它更節省了一行。