<< |
Winsock Programmer's FAQ |
>> |
3.1 - How do I speak { HTTP, POP3, SMTP, FTP, Telnet, NNTP, etc. } with Winsock?Winsock proper does not provide a way for you to speak these protocols, because it only deals with the layers underneath these application-level protocols. However, there are many ways for you to get your program to speak these protocols. Perhaps the easiest method is to use a third-party library. The Resources section lists several of these. Another common method is to use the WinInet library exposed by Microsoft's Internet Explorer. This offers easy access to the HTTP, FTP and Gopher protocols. Newer versions of Microsoft's development tools include classes and controls to access this mechanism. Finally, you can always roll your own. You should start by reading the specifications for the protocol you want to implement. Most of the Internet's protocols are documented in RFCs. The Important RFCs page links to the most commonly referenced application-level RFCs. As far as standards documents go, RFCs are generally clearly-written. Many of the standard protocols are intrinsically simple: they don't require much work to implement. Others may require more work to implement than you may be prepared for. 3.2 - How do I get my IP address from within a Winsock program?There are three methods, which each have advantages and disadvantages:
3.3 - What's the proper way to impose a packet scheme on a stream protocol like TCP?The two most common methods are delimiters and length-prefixing. An example of delimiters is separating packets with, say, a caret (^). Naturally your delimiter must never occur in regular data, or you must have some way of "escaping" delimiter characters. An example of length-prefixing is prepending a two-byte integer containing the packet length on every packet. See the FAQ article How to Use TCP Effectively for the proper way to send integers over the network. There are hybrid methods, too. The HTTP protocol, for example, separates header lines with CRLF pairs (a kind of delimiting), but when an HTTP reply contains a block of binary data, the sever also sends the Content-length header before it sends the data, which is a kind of length-prefixing. I favor simple length-prefixing, because as soon as you read the length prefix, you know how many more bytes to expect. By contrast, delimiters require that you blindly read until you find the end of the packet. 3.4 - How do I write my program to work through a firewall?Most firewalls support the SOCKS protocol for this purpose, either version 4 or version 5. SOCKS allows a client machine on a protected internal network to ask the firewall to act as a relay between it and an Internet host. SOCKS version 5 adds UDP support, as well as some advanced features like end-to-end encryption and secure logins. It's overkill for most applications, but some servers require that you use a SOCKS5-compatible login to get through. You can find out more about SOCKS at the NEC SOCKS site and at Stardust's SOCKS Summit 98 site. You may also want to read the SOCKS5 RFC. Note that a clarified version of this RFC is due out soon; I'll update this Question as soon as I find out about it. The NEC site has a good and free "SOCKSifier" called SOCKSCap that turns almost any Winsock program into a SOCKS-compliant program, so you may not need to modify your app. (There are other vendors that offer SOCKSifiers, and a few non-Microsoft Winsock stacks are SOCKSified. Check your stack's documentation to see if it supports SOCKS natively.) The SOCKSifier method's downside is that your users must set up SOCKSCap and that they must run your program through the SOCKSifier. Thus, it's more user-friendly to implement the SOCKS protocol directly. There is some BSD sockets client-side SOCKS code at the NEC site that you can easily modify to work with Winsock. This is included as part of the Unix SOCKS server package as a library that the included utility programs (rtelnet, rping, etc.) all link to. Note that SOCKS inherently has trouble with some protocols because of the way they operate. Examples of this are RealAudio and almost any "multiuser" protocol, such as multiplayer online games and conferencing programs. These programs require some kind of intelligent proxy that understands the protocol. Unfortunately, these types of proxies are only available for well-established protocols like RealAudio. 3.5 - I'm writing a server. What's a good network port to use?If you're writing a server for an existing, popular Internet protocol, it's already got a port number assigned to it. You can find the most popular of these numbers at the website for the Internet Assigned Numbers Authority (IANA). If you're writing a server for a new protocol, there are a few rules and suggestions you should obey when choosing your server's port:
You should also give some thought to making your program's port
configurable, in case your program is run on a machine where another
server is already using that port. One way to do this is through Winsock's
3.6 - I'm having trouble porting a BSD sockets program to Winsock. Help!There's an article in the FAQ that covers this issue in some detail. 3.7 - How do I send a broadcast packet?With the UDP protocol (but not with TCP) you can send a packet so that all workstations on the network will see it. This can be useful at times, but keep in mind that this creates a load on all the machines on the network, even on machines that aren't listening for the packet. This is because the packet has to go down through several layers of the network stack before it is rejected. As a result, most routers are configured to drop broadcast packets. The practical upshot of that is that broadcasts are usually only effective for programs that only have to work on a single LAN. To get around this problem, you may want to consider multicasting instead. If you still want to use broadcasting, you must first use the
Simple broadcasts have a number of problems, however, so to make sure your broadcasts work properly, you should do a "directed broadcast" instead. A directed broadcast is targeted at a single LAN; some routers will allow you to send a directed broadcast from one LAN to another because they usually cause less disruption than simple broadcasts. Also, some network stacks only respond to certain packets if they are directed broadcasts. For example, a broadcast "ping" packet is usually ignored unless it is directed at one of the LANs that the receiving host is on. A directed broadcast uses a different kind of address. To construct this address, you need to know the LAN's network address and the netmask for that LAN. (You can construct the network address from the address of one of the hosts on the LAN and the netmask.) So, for network 172.16.0.0 with netmask 255.255.0.0, the directed broadcast address is 172.16.255.255. Mathematically, the directed broadcast address is the network address bitwise OR'd with the one's complement of the netmask: u_long host_addr = 0xAC104D58; // 172.16.77.88 u_long net_mask = 0xFFFFE000; // 255.255.224.0 u_long net_addr = host_addr & net_mask; // 172.16.64.0 u_long dir_bcast_addr = net_addr | (~net_mask); // 172.16.95.255 3.8 - When should I turn off the Nagle algorithm?Generally, almost never. Inexperienced Winsockers usually try disabling the Nagle algorithm when they are trying to impose some kind of packet scheme on a TCP data stream. That is, they want to be able to send, say, two packets, one 40 bytes and the other 60, and have the receiver get a 40-byte packet followed by a separate 60-byte packet. (With the Nagle algorithm enabled, TCP will often coalesce these two packets into a single 100 byte packet.) Unfortunately, this is futile, for the following reasons:
Aside from these problems, disabling the Nagle algorithm almost always causes a program's throughput to degrade. The only time you should disable the algorithm is when some other consideration, such as packet timing, is more important than throughput. Often, programs that deal with real-time user input will disable the Nagle algorithm to achieve the snappiest possible response, at the expense of network bandwidth. Three examples are Telnet clients, X Windows servers, and multiplayer network games. In all three cases, it is more important that there be as little delay between packets as possible than it is to conserve network bandwidth. Note that this is a changable issue: back when network bandwidth was truly scarce, Telnet clients usually enabled the Nagle algorithm to save on bandwidth. A contributing factor was that user interfaces in those days tended to be line oriented, whereas modern ones are real-time, with each keystroke potentially changing the entire display. The moral is, consider your application and resources carefully before deciding to disable the Nagle algorithm. For more on this topic, see the Lame List and the FAQ article How to Use TCP Effectively. 3.9 - Is Winsock thread-safe?The Winsock specification does not mandate that a Winsock implementation be thread-safe, but it does allow an implementor to create a thread-safe version of Winsock. Bob Quinn says, on this subject:
By "synchronize activities", I believe Bob means that it may cause
problems if, for example, two threads repeatedly call I believe one thread calling Instead of multiple threads accessing a single socket, you may want to consider setting up a pair of network I/O queues. Then, give one thread sole ownership of the socket: this thread sends data from one I/O queue and enqueues received data on the other. Then other threads can access the queues (with suitable synchronization). Applications that use some kind of non-synchronous socket typically
have some I/O queue already. Of particular interest in this case is
overlapped I/O or I/O completion ports, because these I/O strategies
are also thread-friendly. You can tell Winsock about several OVERLAPPED
blocks, and Winsock will finish sending one before it moves on to the
next. This means you can keep a chain of these OVERLAPPED blocks, each
perhaps added to the chain by a different thread. Each thread can also
call 3.10 - If two threads in an application call
|
<< Information for New Winsockers | Advanced Winsock Issues >> |
Last modified on 29 April 2000 at 15:52 UTC-7 | Please send corrections to tangent@cyberport.com. |
< Go to the main FAQ page |
|
<<< Go to my Home Page |