|
mike7411 wrote: get stuck in the recv function.
I suspect that none of the suggestions in the other post are going to help with this.
Your design is wrong. The message flow looks like this.
- Client- Open socket (server accepts)
- Client- Send request
- Server- Sends response
- Client- Read request
- Client- Closes socket
Notice in the above the server does nothing to terminate the message stream. The client is responsible, not the server.
So recv() sits there waiting for a message that the server will never send.
The HTTP protocol defines a request and then a response.
You however are not following that protocol. At a minimum you are missing the following
1 - You are not checking for a HTTP error code.
2 - You are not reading the 'content-length' header attribute.
3 - You are not looking for the response body.
If you were doing the second then you would use that to read to the end of the message using the content-length. That specifically defines how many bytes the server should send in the response body
Additionally there are additional error conditions that good code must expect
- The content-length might be missing. Invalid HTTP but one must still anticipate that.
- The content-length is too long. Very difficult to deal with. And it still results in the problem you are seeing. So you must add a timeout. Google for how to do that.
What about if the content-length is too short? Myself I just ignore that case. Because in most cases content-length will always be right. And too short might lead to other problems but you have no way to detect that unless you always do a timeout read, and that will slow the application to no point (again because it almost always will be right.)
|
|
|
|
|
|
I wrote some code to copy a file:
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main() {
fs::path source_file("source.txt");
fs::path destination_file("destination.txt");
try {
fs::copy_file(source_file, destination_file);
std::cout << "File copied successfully!" << std::endl;
}
catch (const fs::filesystem_error& e) {
std::cerr << "Error copying file: " << e.what() << std::endl;
}
return 0;
}
Is this a good way of doing it?
Anyone know what buffer sizes are being used behind the scenes?
Thanks.
|
|
|
|
|
|
mike7411 wrote: Is this a good way of doing it?
1. You want to check what happens if different drives are involved.
2. You want to verify paths are supported.
3. Catching one type of exception ignores possible other ones. Probably unlikely but in case.
mike7411 wrote: buffer sizes are being used behind the scenes?
There are all sorts of possible buffers. Disk, OS, library.
Only concern however for that is speed. You can profile it. You can also use a OS command shell call for comparison.
If it matters, at least in my experience, OS shell commands will always be faster. This is especially true when copying directories. Seems reasonable given that the copy operation in the OS doesn't involve loading the data into the application.
Even so if you need it to be 'fast' for some reason then I would suggest that you need to change your requirements/design. Copying files, in general, is always 'slow'. Speed doesn't matter for single small files. So only matters for very large files and/or large numbers of files. But those will always be 'slow'. And there can be error conditions that make it even slower (which your code does not account for.) So attempting to guarantee a speed rate is never going to work.
|
|
|
|
|
I am in Microsoft Visual Studio Community 2022 (64-bit).
I noticed that I can use printf even without including stdio.h.
It works if I do this:
#include <iostream>
Any idea why this works?
Thanks.
|
|
|
|
|
The chain of include files can be long and tortuous. In this particular case:
iostream -> istream -> ostream -> ios -> cstdio -> stdio.h
Should you rely on compiler include chains? Depends if you expect your code to be compiled with a different compiler and how long the chain is. In this particular case, there is a strong probability that all C++ iostream operations will end up like C function calls so you are pretty safe.
Mircea
|
|
|
|
|
I'm looking at the ios file, and I don't see where cstdio gets included.
I did a search in the file for cstdio, and it doesn't seem to be there.
Thanks.
|
|
|
|
|
I skipped a step: ios -> xlocnum -> cstdio.
Mircea
|
|
|
|
|
mike7411 wrote: It works if I do this:
C++
include <iostream>
Any idea why this works?
I guess, because there is a declaration of printf or or this is #included
|
|
|
|
|
iostream provides very complex facilities to C++, and requires a great deal of supporting infrastructure. You can get a list of all the include files that a compilation unit needs by using the /showIncludes flag in your compiles (-H for gcc/clang). Using Compiler Explorer, I see over 100 additional files included, including new , string , istream , ostream , atomic and cstdio (which gets you printf), just to name a few. As others have pointed out, you can just go ahead and use printf for example, and not add #include <cstdio> to your source file. However, as compilers evolve, you may find that this is no longer the case, at which point your code will fail to compile. Its good practice to #include all the relevant headers. System headers, at least, will have guards against multiple inclusions, so there's no harm in being explicit about what headers your program, or module, requires.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
k5054 wrote: Its good practice to #include all the relevant headers
I agree.
This specific case is rather simplistic but in larger applications with company code all over the place relying on chains is just a maintenance (preventable) problem waiting to happen.
|
|
|
|
|
Can someone tell me if this code works to copy a binary file?
while ((ch = fgetc(source)) != EOF) {
fputc(ch, target);
}
What if the file contains a byte that is 255?
Won't it get converted to -1 and break the loop?
Thank you.
|
|
|
|
|
Depends on declaration of ch . If it’s an int (as it should), all is fine as 255 != -1 . If it’s char , it fails, with or without compiler warnings.
Mircea
|
|
|
|
|
|
While your method may work, assuming that ch is an int, and so does not have the 255/-1 issue, your method is horribly inefficient. Richard's suggestion to use fread/fwrite produces much better performance.
For example, given an 8M file, looping through your code 100 times took about 32 seconds. Using a fread/fwrite using a 4K buffer, the same 100 lops took just under 1 second to complete. This was on a PI-3, and successive runs remained stable. I'd expect an 8M file to sit comfortably in the file cache, so the difference is totally down to the difference between extracting a single char at a time, and reading a lot of characters at a time.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
From CP newsletter
The Myth of Smart Pointers – Logikal Blog[^]
Basically complaining about what unique_ptr<t> is defined as.
Myself reading it and looking at the code it seems to me that the author does not understand the difference between the C++ specification and the C++ compiler/runtime.
Which has always been a problem for some people using C/C++ pointers since C (before C++ existed.)
The author seems to be suggesting that the specification is guaranteeing that the memory will be collected. But without even reading the spec I seriously doubt it says that. I suspect it is noting that the it might be collected so one should not rely on it.
There are multiple other places where one can do similar things and it might or might not work depending on compiler, binary and even execution flow (which is really fun to debug.)
Perhaps I am mistaken in what I am reading?
|
|
|
|
|
Given the fact that he is breaking all the rules by branching off into QML (whatever that is, and by his own comments something to be avoided) and Javscript, then you cannot expect C++ to know what is happening outside.
|
|
|
|
|
jschell wrote: The author seems to be suggesting that the specification is guaranteeing that the memory will be collected. But without even reading the spec I seriously doubt it says that. I suspect it is noting that the it might be collected so one should not rely on it. Of course it doesn't guarantee. Where the memory is coming from and where it is going to, is outside the scope of the language specification. From C++11 to C++23 there was some kind of support for garbage collection using std::declare_reachabl e, but it was deleted[^].
Mircea
|
|
|
|
|
It was a silly article, going out of his way to create a bug and then blaming it on the thing he just intentionally broke.
But doing things with C++ that rely on platform/compiler specific details is explicitly allowed, and frequently necessary. The C++ specification alone does not make enough guarantees to result in a useful system - intentionally, so that the details can differ.
|
|
|
|
|
Voluntarily removed - posted in wrong forum...
modified 3-Dec-23 14:27pm.
|
|
|
|
|
37 Questions asked in 2 months starts leaning towards a "Help Vampire". You have not shown us in your code above what you have tried apart from 4 lines of code, which oddly looks AI generated. Please tell us what you have researched so far on how to add second primary menus. If this errors, show the error and we will gladly assist from there.
|
|
|
|
|
|
I’m trying to display an animated bitmap in a win32 application with GDIplus. Last time when I talked about this here I was told I should invalidate a rectangle to force the App to refresh/draw another frame. I’m trying to understand the theory for now. I will come up with code in a day or two if necessary. My question is do you create and invalidate between beginpaint and endpaint a rectangle that has no particular purpose or does it have to be a rectangle that actually does something.
I’m having a difficult time understanding the connection between a rectangle and the rendering process of a win32 api window
|
|
|
|
|
Roughly speaking, the invalidated rectagle will be redrawn in the next WM_PAINT call (other parts of the client area are not redrawn). So, if you need to update a portion of the client area then invalidate the corresponding rectangle and then call UpdateWindow() .
In simple scenarios you can invalidate the entire client area and then call UpdateWindow() .
See, for instance: Invalidating the Client Area - Win32 apps | Microsoft Learn[^].
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|