2010-12-23 57 views
1


我正在做一個網絡服務器,我想出了一些非常奇怪的問題。代碼只能正常運行,如果調試步驟

  1. 我的服務器運行 昨日如預期時,我關掉我的筆記本電腦,但今天只發送HTTP 頭(我沒有改變任何東西)
  2. 當用戶請求一個文件,如果我使用下面的代碼給他們,它完美的作品:

while ((n = fread(data, 1, sizeof(data), file)) > 0) send(ts, data, n, 0);

,但如果我把它改成這樣,它僅發送文件的〜2%。這不是一個隨機數,它實際上只發送大約2%的文件。

while ((n = fread(data, 1, sizeof(data), file)) > 0) 
web.Send(data); 

int WEB::Send(string data) 
{ 
    return send(TempSocket, data.c_str(), data.size(), 0); 
} 

將字符串更改爲char *並不能解決問題。

  • 我正在使用visual studio2010。如果我一步一步運行 我的代碼,我可以通過 解決問題#1,一切都會發送。那是我主要的 問題。我不明白爲什麼 發生。希望有人可以 向我解釋。

在此先感謝。

編輯:在調試時,其表現不同

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd,int nShow) 
{ 
    SOCKET MainSocket=0; 
    MSG msg; 


    RedirectIOToConsole(); 





    CreateThread(NULL, NULL, ListenThread, NULL, NULL, NULL); 



    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 


    WSACleanup(); 
    closesocket(MainSocket); 
    MainSocket = INVALID_SOCKET; 

    return msg.wParam; 
} 

DWORD WINAPI ListenThread(LPVOID lparam) 
{ 
    SOCKET MainSocket; 
    WSADATA wsaData; 
    SOCKET tmpsock; 
    struct sockaddr_in local, from; 
    int fromlen=sizeof(from); 

    WSAStartup(MAKEWORD(2, 2), &wsaData); 


    local.sin_family=AF_INET; 
    local.sin_addr.s_addr=INADDR_ANY; 
    local.sin_port=htons(PORT); 
    MainSocket=socket(AF_INET,SOCK_STREAM,0); 

    if(MainSocket==INVALID_SOCKET) 
    { 
     return 0; 
    } 
    if(bind(MainSocket,(struct sockaddr*)&local,sizeof(local))!=0) 
    { 
     return 0; 
    } 
    if(listen(MainSocket,10)!=0) 
    { 
     return 0; 
    } 


    while(1) 
    { 
     tmpsock = accept(MainSocket,(struct sockaddr*)&from,&fromlen); 
     CreateThread(NULL, NULL, SlaveThread, (LPVOID)tmpsock, NULL, NULL); 
    } 

} 

DWORD WINAPI SlaveThread(LPVOID lparam) 
{ 
    SOCKET ts = (SOCKET)lparam;//temporary socket 
...... 

char data[4096]; 
        int n; 
        unsigned long int length = statbuf.st_size; 

        web.SendHeaders(200, "OK", format("Content-Disposition: attachment; filename=\"%s\"", FileName.c_str()).c_str(), web.GetMimeType(ReqPath.c_str()), length, statbuf.st_mtime); 
        unsigned long int i=0,d=0; 
        while ((n = fread(data, 1, sizeof(data), file)) > 0) 
        { 
         d+=send(ts, data, n, 0); 
         i+=n; 
        } 
        printf("%i=%i=%i\n", length,i,d); 
        fclose(file); 
+1

是否有任何理由將其從工作版本更改爲非工作版本? – msarchet 2010-12-23 15:02:25

+0

原始版本是web.send()。我仍然想使用它,因爲它使代碼更簡潔。 – Cornwell 2010-12-23 15:15:13

+0

我發現了問題所在。在線程結束時,我調用web.disconnect()。該斷開連接功能使用了cancelio,它終止了套接字的所有輸入\輸出。儘管如此,該函數只應在線程結束時調用。我不知道爲什麼它被調用。 – Cornwell 2010-12-23 15:48:57

回答

3

假設datachar[]的一些大小,並且stringstd::string您的代碼不會執行您認爲它的操作。當您將數據傳遞到WEB::Send時,它會從data中的所有字節創建std::string,直到第一個0,這可能佔總數據的2%左右。您想改爲撥打web.Send(std::string(data, n));

也在WEB::Send您需要撥打data.data()而不是c_str()以避免與空值相同的問題。

3

C++代碼幾乎爲始終爲未初始化(或未正確初始化)的變量。

您能告訴我們data的聲明嗎? TempSocket

您將不得不告訴我們更多的代碼告訴你更多。

2

讀取字節可能不等於字符串的實際大小,因爲您每次都不會初始化data循環。但是在第一種情況下,您指定的數據大小等於n,在第二種情況下,您發送的大小爲data.size()。最後可能會有垃圾。

2

從源代碼可以看出,您正在使用線程。我想你必須以適當的方式同步它們。爲什麼?正如你所說的,如果在調試模式下逐步執行,那麼你的程序工作正常;否則它不會。這些執行(逐步執行或整個程序一次)之間的唯一區別是時間。一步一步來得慢,而且顯然有足夠的時間讓一些線程完成一些工作。在某些機器上,即使不改變任何東西,程序也可能正常工作。這是隨機的。所以 - 你必須注意你如何同步線程。

我希望這會有所幫助。

相關問題