CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 25
  1. #1
    Join Date
    Sep 2008
    Posts
    22

    socket receive a chunk at a time

    On linux the same call to fwrite works correctly (errno==0),
    on windows i get ERRNO==22 if the "size" parameter is somewhat big (e.g. "103429"). :-/

    see the code:
    Code:
    // first i open the file
    FILE* request_file = fopen( pathname, "wb" );
    if(request_file == NULL)
    {
       // error
       return;
    }
    
    // second, try to write my buffer (already filled)
    size_t written_bytes = 0;
    if( parsed_request->body != NULL )
    {
       errno=0;
       written_bytes = fwrite((parsed_request->body), 1, (size_t)(parsed_request->content_length), request_file);
       perror("fwrite");
    }
    
    // third, check fwrite return value
    if( written_bytes < 0 )
    {
    	// write error
    	return;
    }
    else if( written_bytes != (parsed_request->content_length) )
    {
    	// error - partial body received
    	return;
    }
    // else fwrite succeed
    NOTE:
    if i replace "(size_t)(parsed_request->content_length)" with a small constant (e.g. "50"), fwrite succeed!

    NOTE2:
    I get the same behavior with "_write"...

    P.S.
    To give you more context details, i'm using the Mingw compiler.
    I've defined the macro "_MT" to enable multi-threaded stdlib.
    Maybe this has some side-effect on fwrite?
    Since the call is not atomic with a big buffer, maybe fwrite fails to preserve thread-safeness?
    I've tried to remove "_MT" in the makefile but fwrite still fails. :-(
    Last edited by hi1; February 6th, 2010 at 10:55 PM.

  2. #2
    Join Date
    Apr 2009
    Posts
    598

    Re: fwrite ERRNO 22 with big (?) size

    The arguments 2 and 3 should be exchanged. This is a common mistake, and, usually, it does not matter, but maybe it matters here.

    Instead of
    Code:
    written_bytes = fwrite((parsed_request->body), 1, (size_t)(parsed_request->content_length), request_file);
    Write
    Code:
    written_bytes = fwrite((parsed_request->body), (size_t)(parsed_request->content_length), 1, request_file);
    Check the value in parsed_request->content_length.
    Is it the size of parsed_request->body?

    N.B. Write your code between [code] and [/code]. It will be placed in a nice rectangle and spaces at the beginning of lines will be saved.

    EDIT: Excuse-me, forget what I have said.
    Last edited by olivthill2; February 2nd, 2010 at 10:00 AM.

  3. #3
    Join Date
    Sep 2008
    Posts
    22

    Re: fwrite ERRNO 22 with big (?) size

    Quote Originally Posted by olivthill2 View Post
    The arguments 2 and 3 should be exchanged. This is a common mistake, and, usually, it does not matter, but maybe it matters here.

    Instead of
    Code:
    written_bytes = fwrite((parsed_request->body), 1, (size_t)(parsed_request->content_length), request_file);
    Write
    Code:
    written_bytes = fwrite((parsed_request->body), (size_t)(parsed_request->content_length), 1, request_file);
    I already tried that. Still get ERRNO==22. :-(
    BTW, the correct way should be the first one. See http://www.opengroup.org/onlinepubs/...ns/fwrite.html):
    I mean to write nitems=(parsed_request->content_length) bytes (size=1) from ptr=(parsed_request->body) to stream=request_file.

    Quote Originally Posted by olivthill2 View Post
    Check the value in parsed_request->content_length.
    Is it the size of parsed_request->body?
    Yes it is.
    Last edited by hi1; February 2nd, 2010 at 05:18 AM.

  4. #4
    Join Date
    Nov 2003
    Posts
    1,902

    Re: fwrite ERRNO 22 with big (?) size

    Don't call perror unless you detect an error.

    gg

  5. #5
    Join Date
    Sep 2008
    Posts
    22

    Re: fwrite ERRNO 22 with big (?) size

    Quote Originally Posted by Codeplug View Post
    Don't call perror unless you detect an error.

    gg
    That call is for debug purpose only.
    I'll remove that once i've fixed the issue.

  6. #6
    Join Date
    Nov 2003
    Posts
    1,902

    Re: fwrite ERRNO 22 with big (?) size

    What issue? You haven't shown any code that actually performs error checking.

    http://www.opengroup.org/onlinepubs/...ons/errno.html

    gg
    Last edited by Codeplug; February 2nd, 2010 at 01:31 PM.

  7. #7
    Join Date
    Sep 2008
    Posts
    22

    Re: fwrite ERRNO 22 with big (?) size

    Quote Originally Posted by Codeplug View Post
    What issue? You haven't shown any code that actually performs error checking.

    gg
    Ok, now i've added the checks.
    I've omitted them since they did not seem relevant to me.
    Last edited by hi1; February 2nd, 2010 at 01:34 PM.

  8. #8
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: fwrite ERRNO 22 with big (?) size

    Quote Originally Posted by hi1 View Post
    Ok, now i've added the checks.
    I've omitted them since they did not seem relevant to me.
    So where exactly in your code do you see that errno is 22?
    Did you step through your code under debugger?
    What is the value of written_bytes? content_length? And what is its type?
    Please note that errno is a global variable, it could be set in some other place in your code.
    For example, if your parsed_request->body is 0, you bypass the line
    Code:
    errno=0;
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  9. #9
    Join Date
    Sep 2008
    Posts
    22

    Re: fwrite ERRNO 22 with big (?) size

    Quote Originally Posted by VladimirF View Post
    So where exactly in your code do you see that errno is 22?
    Did you step through your code under debugger?
    No, perror always output "Invalid Argument" (that is, errno 22).
    I've also disabled multi-threading so there can't be any interference with other threads...

    "content_length" is of "unsigned int" type. It was "103429" when fwrite failed.
    BTW, with smaller values of "content_length" fwrite succeed.
    I'm quite sure fwrite fails because of the "nitems" param, but i can't understand why.
    Last edited by hi1; February 2nd, 2010 at 03:10 PM.

  10. #10
    Join Date
    Nov 2003
    Posts
    1,902

    Re: fwrite ERRNO 22 with big (?) size

    How do you know that fwrite fails? Can we see the code?

    gg

  11. #11
    Join Date
    Sep 2008
    Posts
    22

    Re: fwrite ERRNO 22 with big (?) size

    Quote Originally Posted by Codeplug View Post
    How do you know that fwrite fails? Can we see the code?

    gg
    Boy, it's just what i've posted:
    If fwrite succeed errno remains 0 and perror outputs "No error",
    otherwise errno!=0 and perror output something meaningful.

  12. #12
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: fwrite ERRNO 22 with big (?) size

    OK, last question: how sure are you that content_length matches the length of body?
    If body is shorter, it will cause access violation during write() that will be caught inside that function and translated into EINVAL.
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  13. #13
    Join Date
    Nov 2003
    Posts
    1,902

    Re: fwrite ERRNO 22 with big (?) size

    >> http://www.opengroup.org/onlinepubs/...ons/errno.html
    ... The value of errno shall be defined only after a call to a function for which it is explicitly stated to be set and until it is changed by the next function call or if the application assigns it a value. The value of errno should only be examined when it is indicated to be valid by a function's return value. ...
    >> http://www.opengroup.org/onlinepubs/...ns/fwrite.html
    RETURN VALUE

    The fwrite() function shall return the number of elements successfully written, which may be less than nitems if a write error is encountered. If size or nitems is 0, fwrite() shall return 0 and the state of the stream remains unchanged. Otherwise, if a write error occurs, the error indicator for the stream shall be set, [CX] and errno shall be set to indicate the error.
    So you can only check errno if frwite() returns a value less than the number of elements requested, or if ferror() returns non-zero.

    gg

  14. #14
    Join Date
    Sep 2008
    Posts
    22

    Re: fwrite ERRNO 22 with big (?) size

    Quote Originally Posted by VladimirF View Post
    OK, last question: how sure are you that content_length matches the length of body?
    If body is shorter, it will cause access violation during write() that will be caught inside that function and translated into EINVAL.
    Yes i've thinked of it too, but the test case i've used for testing is build so that the content_length matches exactly the length of the body buffer.
    So you can assume that this condition is always true.

    Quote Originally Posted by Codeplug View Post
    So you can only check errno if frwite() returns a value less than the number of elements requested, or if ferror() returns non-zero.
    gg
    Ok, but the problem here is not if the errno value is valid or not.
    The problem is that fwrite does not write anything (written_bytes==0) even if the arguments are correct.

    Also note that (as i've already stated) that the very same code works correctly on Linux (written_bytes==103429),
    so i'm quite sure that the program logic is correct.
    I guess there must be "something" in the Windows context that makes fwrite behave differently.

    I hope i've made myself clear. :-)
    Last edited by hi1; February 2nd, 2010 at 07:04 PM.

  15. #15
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: fwrite ERRNO 22 with big (?) size

    Quote Originally Posted by hi1 View Post
    ...the test case i've used for testing is build so that the content_length matches exactly the length of the body buffer.
    So you can assume that this condition is always true.
    I prefer to assume that it isn't.
    Could you look at your "body" in the debugger? Can you scroll the Memory window all the way to body+103429? Does it look OK?
    Bottom line is - I can assure you that fwrite() can handle 100K on Windows.
    Could you package your test case and post it here?
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured