Beej's Guide to Network Programming The XSL-FO output is then munged by Apache FOP to produce PDF documents, using Liberation fonts. This is my little how-to guide on network programming using Internet sockets, or " sockets programming", for those of you who prefer it. The sockets API, though. Beej's Guide to Network Programming. Using Internet .. are just starting out with socket programming and are looking for a foothold. It is certainly not Second edition ISBNs: , , There is a third.
|Language:||English, Spanish, Indonesian|
|Genre:||Fiction & Literature|
|Distribution:||Free* [*Registration needed]|
Hey! Socket programming got you down? Is this stuff just a little too difficult to figure out from the man pages? You want to do cool Internet. [PDF] Beej's Guide to Network Programming Using Internet Sockets The late W . Richard Steven's UNIX Network Programming still holds the. If you want to get Programming Windows pdf eBook copy write by good author, you can download Version Beej's Guide to Network Programming.
The book is readable, with lots of diagrams and packet trace decodes. Some points missing, such as TCP congestion avoidance. Case studies, included for every subject, include sniffer output and explanations. Covers the material in depth and clarity, giving good background of the subject.
This book is UNIX oriented. Unix Network Programming By W. Due to Richard Steven's death on Sep 1st , I'm in the dark regarding this books's future. Unix System V. Network Programming By Steven A. The Design and Implementation of the 4. Karels and John S. Linux Kernel Internals By M. Beck, H. Bohme, M. Dziadzka, U. Kunitz, R.
Magnus, and D. Covers the history of the subject, it's rational, and it's working in detail. Security is well covered, in contrast to other books on the subject. Focuses on BGP4 and is, naturally, oriented toward Cisco's way of doing it which is not much of a limit, considering Cisco's dominance of the routers market.
The four chapters include an introduction, the protocol, operations, and extensions scaling, route flap dampening, authentication, negotiation, etc. Computer Networks By Andrew S. Tanenbaum Published by Prentice-Hall. Gives an excellent framework to Internet security. Back to Top 1. Computer Networks and Internets, by Douglas E.
Data Communications magazine has a collection of technical tutorials available at it's site, covering such subjects as ATM, IP, high speed networking, etc. First Monday is a journal about the Internet which is published on the internet, with all it's articles peer-reviewed. Ross and James F. The Cooperative Association for Internet Data Analysis maintains a list of pointers to Internet Engineering related university courses. Those are specs, not hands-on manuals. Three other good places to look for RFCs are - 1.
By email to rfc-info isi. An excellent index of RFCs is available in an appendix in Comer's first volume, but it is current as of the publishing date only. Back to Top 2. Those groups, along with news. The content of the site was reviewed by the readership of the comp.
The comp. Easy enough. If it puts fewer in. Beej's Guide to Network Programming If you're only getting one single connection ever, you can close the listening sockfd in order to prevent more incoming connections on the same port, if you so desire. These two functions are for communicating over stream sockets or connected datagram sockets. If you want to use regular unconnected datagram sockets, you'll need to see the section on sendto and recvfrom , below.
The send call: Just set flags to 0. See the send man page for more information concerning flags. Some sample code might be: See, sometimes you tell it to send a whole gob of data and it just can't handle it. It'll fire off as much of the data as it can, and trust you to send the rest later.
Remember, if the value returned by send doesn't match the value in len, it's up to you to send the rest of the string. The good news is this: Again, -1 is returned on error, and errno is set to the error number. The recv call is similar in many respects: See the recv man page for flag information. This can mean only one thing: A return value of 0 is recv 's way of letting you know this has occurred.
There, that was easy, wasn't it? You can now pass data back and forth on stream sockets! You're a Unix Network Programmer! We have just the thing. Since datagram sockets aren't connected to a remote host, guess which piece of information we need to give before we send a packet?
That's right! The destination address! Here's the scoop: To get your hands on the destination address structure, you'll probably either get it from getaddrinfo , or from recvfrom , below, or you'll fill it out by hand. Just like with send , sendto returns the number of bytes actually sent which, again, might be less than the number of bytes you told it to send!
Equally similar are recv and recvfrom. The synopsis of recvfrom is: When the function returns, fromlen will contain the length of the address actually stored in from.
So, here's a question: Because, you see, we want to not tie ourselves down to IPv4 or IPv6. Seems extraneous and redundant, huh. The answer is, it just isn't big enough, and I'd guess that changing it at this point would be Problematic.
So they made a new one. Remember, if you connect a datagram socket, you can then simply use send and recv for all your transactions. The socket itself is still a datagram socket and the packets still use UDP, but the socket interface will automatically add the destination and source information for you.
You've been send ing and recv ing data all day long, and you've had it. You're ready to close the connection on your socket descriptor. This is easy. You can just use the regular Unix file descriptor close function: Anyone attempting to read or write the socket on the remote end will receive an error. Just in case you want a little more control over how the socket closes, you can use the shutdown function.
It allows you to cut off communication in a certain direction, or both ways just like close does. If you deign to use shutdown on unconnected datagram sockets, it will simply make the socket unavailable for further send and recv calls remember that you can use these if you connect your datagram socket.
It's important to note that shutdown doesn't actually close the file descriptor—it just changes its usability. To free a socket descriptor, you need to use close. Nothing to it. Except to remember that if you're using Windows and Winsock that you should call closesocket instead of close.
This function is so easy. It's so easy, I almost didn't give it its own section. But here it is anyway. The function getpeername will tell you who is at the other end of a connected stream socket. The synopsis: The function returns -1 on error and sets errno accordingly. No, you can't get their login name. Ok, ok. If the other computer is running an ident daemon, this is possible. This, however, is beyond the scope of this document.
Check out RFC for more info. Even easier than getpeername is the function gethostname. It returns the name of the computer that your program is running on. The name can then be used by gethostbyname , below, to determine the IP address of your local machine. What could be more fun?
I could think of a few things, but they don't pertain to socket programming. Anyway, here's the breakdown: The function returns 0 on successful completion, and -1 on error, setting errno as usual. Just about everything on the network deals with client processes talking to server processes and vice-versa. The exchange of information between client and server is summarized in the above diagram.
The server code Client-Server Interaction. All you need to do to test this server is run it in one window. Take telnet. Every time you use ftp. It handles the incoming telnet connection.
Client-Server Background It's a client-server world. When you connect to a remote host on port 23 with telnet the client. The basic routine is: This is what our sample server does in the next section.
IPv4 or IPv6: Beej's Guide to Network Programming 26 while waitpid The client source Beej's Guide to Network Programming 27 if listen sockfd. You can get the data from this server by using the client listed in the next section. It gets the string that the server sends. I have the code in one big main function for I feel syntactic clarity. Feel free to split it into smaller functions if it makes you feel better.
If you make lots of zombies and don't reap them. The code that's there is responsible for reaping zombie processes that appear as the fork ed child processes exit. All this client does is connect to the host you specify on the command line.
A Simple Stream Client This guy's even easier than the server. Beej's Guide to Network Programming 29 printf "client: Here is the source for listener. Datagram Sockets We've already covered the basics of UDP datagram sockets with our discussion of sendto and recvfrom. Very useful. This is one of the perks of using unconnected datagram sockets! Next comes the source for talker. Beej's Guide to Network Programming 32 And that's all there is to it!
Run listener on some machine. Except for one more tiny detail that I've mentioned many times in the past: Let's say that talker calls connect and specifies the listener's address. From that point on. I need to talk about this here. For this reason. Watch them communicate!
Fun G-rated excitement for the entire nuclear family! You don't even have to run the server this time! You can run talker by itself. Slightly Advanced Techniques These aren't really advanced. Blocking Blocking. By setting a socket to non-blocking. Generally speaking. I'll offer the synopsis of select: When you first create the socket descriptor with socket.
Have at it! One possible alternative is libevent Take the following situation: If you put your program in a busy- wait looking for data on the socket. If you don't want a socket to be blocking. The reason they can do this is because they're allowed to.
Which do you check for? The specification doesn't actually specify which your system will return. What if you're blocking on an accept call? How are you going to recv data at the same time? You don't want to be a CPU hog. A more elegant solution for checking to see if there's data waiting to be read comes in the following section on select. All the recv functions block. You've heard about it—now what the heck is it?
In a nutshell. Not so fast. It'll tell you which ones are ready for reading. You probably noticed that when you run listener. This being said. No problem. If you try to read from a non-blocking socket and there's no data there. What happened is that it called recvfrom. So here we go into the brave new world of some of the more esoteric things you might want to learn about sockets.
Lots of functions block. In this example..
When select returns. The following code snippet25 waits 2. There are 1. The following macros operate on this type: This time structure allows you to specify a timeout period. We have a microsecond resolution timer! Clear all entries from the set. If you set the parameter timeout to NULL. I'll talk about how to manipulate these sets. If you want to see if you can read from standard input and some socket descriptor.
The struct timeval has the follow fields: This depends on what flavor of Unix you're running. Before progressing much further. Remove fd from the set. The parameter numfds should be set to the values of the highest file descriptor plus one. You'll probably have to wait some part of your standard Unix timeslice no matter how small you set your struct timeval. Return true if fd is in the set. If the time is exceeded and select still hasn't found any ready file descriptors.
Beej's Guide to Network Programming 34 int select int numfds. Other things of interest: If you set the fields in your struct timeval to 0. Add fd to the set. Don't rely on that occurring if you want to be portable.
But others do not. This program26 acts like a simple multi-user chat server. You should see what your local man page says on the matter if you want to attempt it. But have a look. I know. One more note of interest about select: That's how you know the client has closed the connection. Some Unices can use select in this manner. Beej's Guide to Network Programming 35 struct timeval tv. When you actually do recv from it. And that. Some Unices update the time in your struct timeval to reflect the amount of time still remaining before a timeout.
It's a bummer. When you type something in one telnet session. Use gettimeofday if you need to track time elapsed. Start it running in one window. What happens if a socket in the read set closes the connection? Beej's Guide to Network Programming 37 exit 3.
Due to circumstances beyond your control.
You could write a function like this to do it. I know some data has been received. So I get it. I must store these safely away somewhere. I have to add it to the master set? And every time a connection closes. What happened to the remaining bytes? The first. Notice I check to see when the listener socket is ready to read.
I know the client has closed the connection.. At the last minute. If the client recv returns non-zero. When it is. The reason I have the master set is that select actually changes the set you pass into it to reflect which sockets are ready to read. Check it out! Handling Partial send s Remember back in the section about send. I have to remove it from the master set? That is.
But doesn't this mean that every time I get a new connection. Since I have to keep track of the connections from one call of select to the next. In addition. This means it will block on the read after the select says it won't!
Why you little—! Sometimes a human-readable protocol is excellent to use in a non-bandwidth-intensive situation. I prefer the third method. The receiver will parse the text back into a number using a function like strtol. Convert the number into text with a function like sprintf.
Just send the data raw. This will be the same number of bytes you asked it to send. Method two: So hunt around and do your homework before deciding to implement this stuff yourself. This one is quite easy but dangerous! The receiver will decode it. For completeness. Sneak preview!
Tonight only! Serialization—How to Pack Data It's easy enough to send text data across the network. Beej's Guide to Network Programming 39 The function returns -1 on error and errno is still set from the call to send. Encode the number into a portable binary form. The first method. I include the information here for those curious about how things like this work. See the fcntl reference page for more info on setting a socket to non-blocking.
Actually all the methods. I should tell you that there are libraries out there for doing this. It turns out you have a few options. If the packets are variable length. You probably have to encapsulate remember that from the data encapsulation section way back there at the beginning? Read on for details! Quick note to all you Linux fans out there: Usage is fairly straightforward: I did.
Hey—maybe you don't need portability. And since there's no standard way in C to do this. To reverse unencode the number. When packing integer types. But didn't I just get finished saying there wasn't any such function for other non-integer types?
Is all hope lost? Fear not! Were you afraid there for a second? Not even a little bit? There is something we can do: The code is decidedly non-portable. Beej's Guide to Network Programming 40 send s. The thing to do is to pack the data into a known format and send that over the wire for decoding.
That's what htons and its ilk do. What can we do instead? Mostly—it doesn't encode NaN or Infinity. On the other hand. On the minus side.
You can also see in the above example that the last couple decimal places are not correctly preserved. Here's some code that encodes floats and doubles into IEEE format Most computers use this format internally for doing floating point math. But if you want your source code to be portable. Here's sample usage: Beej's Guide to Network Programming 42 long long shift. Zeus saves a kitten every time I recommend it.
But if you want to write your own packing utility in C. One thing you can do is write a helper function to help pack the data for you. The Practice of Programming is an excellent read. Python and Perl programmers will want to check out their language's pack and unpack functions for accomplishing the same thing.
That's a lot of work. At this point. To quote a friend. Here's a version I cooked up33 on my own based on that which hopefully will be enough to give you an idea of how such a thing can work. It'll be fun! This code references the pack functions. Back to it: I always blame Microsoft. And Java has a big-ol' Serializable interface that can be used in a similar way. I'd link to them.
Beej's Guide to Network Programming 43 Another question you might have is how do you pack structs? Unfortunately for you. Beej's Guide to Network Programming 47 case 'g': Beej's Guide to Network Programming 48 case 'c': You've found the Runestaff! Be wary when unpacking data you get over the network—a malicious user might send badly-constructed packets in an effort to attack your system! Beej's Guide to Network Programming 49 break. How does the client know when one message starts and another stops?
You could. What should your header look like? Why did I choose the 8-byte and byte limits for the fields?
I pulled them out of the air. The problem is that the messages can be of varying lengths. But you're not obligated to. That's vague. When packing the data. So far so good? At least. So we encapsulate the data in a tiny header and packet structure. Beej's Guide to Network Programming 50 Whether you roll your own code or use someone else's.
NUL-padded if necessary. RFC Son of Data Encapsulation What does it really mean to encapsulate data. The Packet Police are not right outside your door.
Don't look now. In any case. Excellent question. I suggest conforming to that if you're going to roll the data yourself. Your outgoing data stream looks like this: And so on. Let's have a look a sample packet structure that we might use in this situation: Using the above packet definition. The length of the packet should be calculated as the length of this data plus 8 the length of the name field.
I don't think they are. But that wastes bandwidth! And then let's assume the data is variable length. In the simplest case. The choice is up to you. When you've handled the first one. The advantage of this method is that you only need a buffer large enough for one packet.
Another option is just to call recv and say the amount you're willing to receive is the maximum number of bytes in a packet. But this is why you made your work buffer large enough to hold two packets—in case this happened!
Since you know the length of the first packet from the header. Every time you recv data. If you're still curious. Broadcast Packets—Hello. Are you juggling that in your head yet? Once the packet is complete.
Unfortunately for the rest of you. I did say it was easy. And it is.
What you can do is declare an array big enough for two packets. You have to make a special case for this. But how? Since you know every packet starts off with a length. Bloody heck. But it is possible. I insist. Then once you have that. There are actually a couple things you can do here. Then whatever you get. This is your work array where you will reconstruct packets as they arrive. Use it. So far. By Excalibur I swear it! When you're sending this data. I never said it was easy. With IPv6.
But enough of the starry-eyed future—we're stuck in the bit present. To be safe. Some of you readers will note that actually moving the partial second packet to the beginning of the work buffer takes time. We need to call recv over and over again until the packet is completely received. If the number of bytes in the buffer is less than 1. Routers do not forward this type of broadcast packet off your local network. We'll call this program broadcaster. It varies.
You can send this type of broadcast packet to remote networks as well as your local network. Many machines will automatically bitwise AND this with your network number to convert it to a network broadcast address.
Send the data to a specific subnet's broadcast address. Is there really more than one way to skin a cat? What kind of expression is that? If they didn't drop it. Permission denied Yes. Beej's Guide to Network Programming 52 But wait! You can't just run off and start broadcasting willy-nilly. It's like a one of those little plastic covers they put over the missile launch switch!
That's just how much power you hold in your hands! But seriously. If you're curious. Under Unix. When the game Doom first came out. There are two common ways: And then it hands the data over or discards it. This is This is the subnet's network number with all one-bits set for the host portion of the address.. So my broadcast address is Do that. In either case. With the exception of the client being allowed to send broadcast packets in this case.
You should be now be able to do all those sends that failed. Beej's Guide to Network Programming 54 sent 3 bytes to Since every machine on the LAN will be forced to deal with the packet whether it recvfrom s it or not. Pat and Bapper. I told you I'd mention you in the guide. Both listeners get the packet even though you only called sendto once!
If the listener gets data you send directly to it. They are definitely to be used sparingly and appropriately. So nyah. But now fire up listener on another machine next to you on the same network so that you have two copies going. If listener doesn't respond. Richard Stevens would give you. Then you call select with whatever timeout you want.
The gist of it is that you make a socket descriptor with socket. What is ICMP? All your raw sockets questions will be answered in W. Check the manual for your particular platform. Common Questions Where can I get those header files?
If you don't have them on your system already. How can I tell if the remote side has closed connection? You can tell because recv will return 0.
If you're building for Windows. How do I change or shorten the timeout on a call to connect? Instead of giving you exactly the same answer that W. Check out the section on bind and the section on select for an example. Check the man page for full details.
Run the client in one window and the server in another. In short. How do I get a list of open sockets on the system? Use the netstat. How can I run the client and server programs if I only have one computer?
Don't I need a network to write network programs? Fortunately for you. If it doesn't timeout. When you've called select and timed- out. My favorite solution to this involves a goto statement. Why does select keep falling out on a signal? I keep getting linker errors when I try to compile!
The linker errors happen because Sun boxes don't automatically compile in the socket libraries. You know this irritates your professors to no end. When you set up a signal handler with sigaction. Like I said. But I think the goto statement is actually cleaner. How can I implement a timeout on a call to recv? Use select! It allows you to specify a timeout parameter for socket descriptors that you're looking to read from.
Beej's Guide to Network Programming 56 Finally. Notice that this has the added benefit of allowing your program to do something else while it's connecting.
How do I build for Windows? So all you need to do to use my code is to find the place between where the data is read and the data is sent using send over the network. Notice that recvtimeout returns -2 in case of a timeout.
Check out the OpenSSL project39 for more info. But assuming you want to plug in or implement your own compressor or encryption system. Each step changes the data in some way. So that return value is already spoken for. Why not return 0?
How do I encrypt or compress the data before sending it through the socket? One easy way to do encryption is to use SSL secure sockets layer. See the section on socket for details. I don't know how to use CreateProcess —it takes a bazillion arguments. I'm on a Windows box and I don't have the fork system call or any kind of struct sigaction.
What to do? If they're anywhere. What's going on? You're hitting the MTU—the maximum size the physical medium can handle. And maybe even sigaction. But on Ethernet. It deletes everything in your account. I'm sending a slew of data. See the sendall function implementation for details.
If that doesn't work at all. The process the client follows is this: Beej's Guide to Network Programming 58 How can I write a server that accepts shell commands from a client and executes them?
For simplicity. On the local machine. I really can't tell you the answer. Once you're sure of that. So you get wise. 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. You have to make sure all the data is being sent. Since I don't have a Windows box. Over a modem. But if I run it on my local machine. Read the section Son of Data Encapsulation for details on receiving complete packets of data using multiple calls to recv.
As you can see. If you're writing just your own specialized server. You'll have a socket of some type that you can read this data from. This is the basis for how a packet sniffer works. You have to make sure you don't give bad people access to the internal network.
If that's not satisfactory. How do I put my Ethernet interface into promiscuous mode? For those not in the know. There's what looks like a decent writeup in Linux Journal If you're writing. Beej's Guide to Network Programming 59 I'm behind a firewall—how do I let people outside the firewall know my IP address so they can connect to my machine? Don't make your sysadmin mad at me. If the port is already in use. The Linux man page suggests using alarm or setitimer as a substitute.
We're talking Ethernet-layer addresses here. The firewall can forward to you either through it's NAT software. This isn't to say that all is lost. All that matters is that no one else on the same machine is using that port when you want to use it. It depends on your system. Choose another port. Be aware that a hole in the firewall is nothing to be taken lightly. How can I tell which ports are available to use?
Usually this isn't an issue. It's a good idea to allow the user of your software to specify an alternate port either with a config file or a command line switch. Just design your programs so that you're always the one initiating the connection. Just because something over is in that list doesn't mean you can't use the port. It puts the interface into promiscuous mode. Man Pages In the Unix world. And speaking of the examples. But wait! That's not all that's wrong with my man pages: I'm sure Microsoft Visual Studio has something similar in their help section.
They have little sections that describe individual functions that you have at your disposal. If you want the real information. I don't tend to put in all the error checking because it really increases the length of the code. Indeed I could go on and on at great length about how much I prefer to be terse but instead I shall be brief and not bore you with long-winded diatribes about how utterly amazingly brief I prefer to be in virtually all circumstances in their entirety.
Unix wins again! The old socket that you are using for listening is still there. Beej's Guide to Network Programming 61 9. Return Value accept returns the newly connected socket descriptor. If so. The socket descriptor returned by accept is a bona fide socket descriptor. You have to close it when you're done with it. See Also socket.