Author : Beej
Page : << Previous 14
say the client connect()s, send()s, and close()s the connection (that is, there are no subsequent system calls without the client connecting again.)
The process the client follows is this:
connect() to server
send("/sbin/ls > /tmp/client.out")
close() the connection
Meanwhile, the server is handling the data and executing it:
accept() the connection from the client
recv(str) the command string
close() the connection
system(str) to run the command
Beware! Having the server execute what the client says is like giving remote shell access and people can do things to your account when they connect to the server. For instance, in the above example, what if the client sends "rm -rf ~"? It deletes everything in your account, that's what!
So you get wise, and you prevent the client from using any except for a couple utilities that you know are safe, like the foobar utility:
if (!strcmp(str, "foobar")) {
sprintf(sysstr, "%s > /tmp/server.out", str);
system(sysstr);
}
But you're still unsafe, unfortunately: what if the client enters "foobar; rm -rf ~"? The safest thing to do is to write a little routine that puts an escape ("\") character in front of all non-alphanumeric characters (including spaces, if appropriate) in the arguments for the command.
As you can see, security is a pretty big issue when the server starts executing things the client sends.
Q: I'm sending a slew of data, but when I recv(), it only receives 536 bytes or 1460 bytes at a time. But if I run it on my local machine, it receives all the data at the same time. What's going on?
A: You're hitting the MTU--the maximum size the physical medium can handle. On the local machine, you're using the loopback device which can handle 8K or more no problem. But on ethernet, which can only handle 1500 bytes with a header, you hit that limit. Over a modem, with 576 MTU (again, with header), you hit the even lower limit.
You have to make sure all the data is being sent, first of all. (See the sendall() function implementation for details.) Once you're sure of that, then you need to call recv() in a loop until all your data is read.
Read the section Son of Data Encapsulation for details on receiving complete packets of data using multiple calls to recv().
Q: I'm on a Windows box and I don't have the fork() system call or any kind of struct sigaction. What to do?
A: If they're anywhere, they'll be in POSIX libraries that may have shipped with your compiler. Since I don't have a Windows box, I really can't tell you the answer, butI seem to remember that Microsoft has a POSIX compatibility layer, and that's where fork() would be. (And maybe even sigaction.)
Search the help that came with VC++ for "fork" or "POSIX" and see if it gives you any clues.
If that doesn't work at all, ditch the fork()/sigaction stuff and replace it with the Win32 equivalent: CreateProcess(). I don't know how to use CreateProcess()--it takes a bazillion arguments, but it should be covered in the docs that came with VC++.
Well, that's the lot of it. Hopefully at least some of the information contained within this document has been remotely accurate and I sincerely hope there aren't any glaring errors. Well, sure, there always are.
So, let this be a warning to you! I'm sorry if any inaccuracies contained herein have caused you any grief, but you just can't hold me accountable. See, I don't stand behind a single word of this document, legally speaking. The whole thing could be completely and utterly wrong!
But it's probably not. After all, I've spent many many hours messing with this stuff, and implemented several TCP/IP network utilities at work, have written multiplayer game engines, and so on. But I'm not the sockets god; I'm just some guy.
By the way, if anyone has any constructive (or destructive) criticism about this document, please send mail to <beej@piratehaven.org> and I'll try to make an effort to set the record straight.
In case you're wondering why I did this, well, I did it for the money. Ha! No, really, I did it because a lot of people have asked me socket-related questions and when I tell them I've been thinking about putting together a socket page, they say, "Cool!" Besides, I feel that all this hard-earned knowledge is going to waste if I can't share it with others. The web just happens to be the perfect vehicle. I encourage others to provide similar information whenever possible.
Enough of this--back to coding! ;-)
Page : << Previous 14