6 ms·
Pretty much the same minimal http server in C: #include <WinSock.h> #include <stdio.h> #pragma comment(lib, "wsock32.lib") int main(int argc, c
by corysama 12y ago
Pretty much the same minimal http server in C:
#include <WinSock.h>
#include <stdio.h>
#pragma comment(lib, "wsock32.lib")
int main(int argc, const char *argv[]) {
WSADATA wsadata;
WSAStartup(2, &wsadata);
sockaddr_in address;
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("0.0.0.0");
address.sin_port = htons(80);
int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(sock, (struct sockaddr *)&address, sizeof(address));
for(;;) {
listen(sock, 0);
int connection = accept(sock, NULL, NULL);
char recvBuffer[1024];
int recvSize = recv(connection, recvBuffer, sizeof(recvBuffer)-1, 0);
recvBuffer[recvSize]=0;
printf(recvBuffer);
char response[] = "HTTP/1.1 200 OK\nContent-Type: text/html\n\nlol";
send(connection, response, sizeof(response), 0);
closesocket(connection);
}
return 0;
}
- _asummers 12y agoWhy is for(;;) used instead of while(true)? I've seen this idiom used many times but never understood the reasoning why. According to this[0] SO, there are no performance gains, so why would one prefer the for version? [0] http://stackoverflow.com/questions/2288856/when-implementing-an-infinite-loop-is-there-a-difference-in-using-while1-vs-f http://stackoverflow.com/questions/2288856/when-implementing...
- LeonRobrotsky 12y ago7 vs 11 characters and I'm lazy.
- corysama 12y agoThey are equivalent. It's just a matter of personal preference. I like it because it's shorter and it doesn't read as a loop that evaluates the value 'true' on each iteration. Even though you know the evaluation optimizes away trivially if you think about it, I don't even want to think that far when I'm scanning code.
- nchelluri 12y agoI had a professor who gave some reasoning about this. He's written a paper: http://plg.uwaterloo.ca/~pabuhr/papers/MELoop.ps http://plg.uwaterloo.ca/~pabuhr/papers/MELoop.ps I haven't read the whole thing but I like this bit: > There are many algorithms that are best written using an exit from the middle of a loop. If not written in this fashion, techniques such as the traditional “priming” of a loop must be used. For example, in reading a file: read(a, b, c) WHILE NOT eof DO { process a, b, & c } read(a, b, c) END WHILE LOOP read(a, b, c) WHEN eof EXIT { process a, b, & c } END LOOP > The example on the left [top] shows the priming of a loop. This requires duplication of the READ statement or, in other cases, creation of a subprogram to eliminate the duplication, both of which are undesirable. As well, loop priming can be done an arbitrary distance before the beginning of the loop making the program difficult to read as the priming statement(s) is critical to the understanding of the loop.
- ternaryoperator 12y agoIn the first versions of C, 'true' was not a keyword, so for(;;) was the way an endless loop was encoded. After that, it became the convention.
- pcthrowaway 12y agoI just started learning Go last night, but I'll hazard a guess: since Go draws heavily from C, but has the for loop as its only looping construct, it seems likely that this habit has carried back into C code written by developers who've used Go, or who've been reading a lot C code written by developers who also use Go.
- jsprogrammer 12y agofor(;;) existed way before Go came along.
- pcthrowaway 12y agoI'm not saying it didn't, but 'while (true)' would be the more intuitive way to write that in any language besides Go.
- throwawayfor 12y agoAnother reason is that MSVC whines about loop conditionals evaluating to constants. Or at least it used to. So while(1) would cause a warning, but not for(;;)
- phodo 12y agoSee this list of winsock alternatives if trying on non-windows http://tangentsoft.net/wskfaq/articles/othersys.html http://tangentsoft.net/wskfaq/articles/othersys.html
- Elizer0x0309 12y agoThis is more inline with what the blog's author should've done with all the grandiose intro of trying to understand the underlying system. Good work!
- mhogomchungu 12y ago> char response[] = "HTTP/1.1 200 OK\nContent-Type: text/html\n\nlol"; isnt it better to write that as: const char* response = "HTTP/1.1 200 OK\nContent-Type: text/html\n\nlol"; ? Having the string in a writable buffer when you have no intention of modifying the string seems like not a very good idea. Any decent compiler will evaluate "strlen(response)" at compile time and hence there will be no run time penalty here.
- exDM69 12y ago> Having the string in a writable buffer when you have no intention of modifying the string seems like not a very good idea. Any decent compiler will also notice this and put the string literal in the .RODATA section. Using "const" doesn't really make a difference, it's more of a hint for the compiler. It really doesn't make any difference in this case.
- smoyer 12y agoIt may be a hint to modern compilers, but it's also the documentation of intent for future developers[1]. [1] Where future developers includes me - I'll forget what I wrote in six months or less.
- mattstreet 12y agoNot just as documentation, it would prevent another developer from accidentally modifying it.
- smoyer 12y agoExcellent point ... I kind of assumed that (your IDE giving you a warning that you're trying to modify a constant) when I was thinking about it as documentation but your point more succinctly describes "making it hard to make mistakes".
- Matheus28 12y agoIt does, the compiler doesn't know what the function "send" will do. The const isn't the focus of what he said, it's allocating in the stack vs in a read-only memory location.