只有在逐步调试时,代码才能正常运行

时间:2010-12-23 14:57:22

标签: c++ windows visual-studio


我正在制作一个网络服务器,我想出了一些非常奇怪的问题。

  1. 我的服务器按预期运行 昨天我关掉笔记本电脑,但今天它只发送了http 标题(我没有改变任何东西)
  2. 当用户请求文件时,如果我使用以下代码发送文件,则它可以完美地运行:
  3. 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);
    

4 个答案:

答案 0 :(得分:3)

在调试时行为不同的C ++代码几乎总是未初始化(或初始化不正确)的变量。

您能告诉我们data的声明吗? TempSocket

您必须向我们展示更多代码,以告诉您更多信息。

答案 1 :(得分:3)

假设data是某个大小的char[],并且stringstd::string,那么您的代码就不会按照您的想法执行。当您将数据传递给WEB::Send时,它会从std::string中的所有字节创建data直到第一个0,这可能约占总数据的2%。您想改为呼叫web.Send(std::string(data, n));

同样在WEB::Send中,您需要致电data.data()而不是c_str(),以避免出现与空值相同的问题。

答案 2 :(得分:2)

读取字节数可能不等于字符串的实际大小,因为每次循环都不会初始化data。但在第一种情况下,您指定的数据大小等于n,在第二种情况下,您发送的大小为data.size()。最后可能会有垃圾。

答案 3 :(得分:2)

从您的源代码中可以看出,您正在使用线程。我想你必须以适当的方式同步它们。为什么?正如您所说,如果在调试模式下逐步执行,您的程序将正常工作;否则它没有。这些执行(一步一步或整个程序一次)的唯一区别是时间。一步一步变慢,并且显然有足够的时间让一些线程完成某项工作。在某些机器上,即使您没有更改任何内容,您的程序也可能正常工作。这是随机性。所以 - 你必须注意如何同步线程。

我希望这会有所帮助。