⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 44.htm

📁 网络编程原理文摘 [文件] 精华区目录结构 [目录] 网络编程的基本原理 [目录] 网络编程与网络协议 [目录] 网上资源 [目录] winsock技术 [目录
💻 HTM
📖 第 1 页 / 共 5 页
字号:
     There are other options, such as select() and event objects, but they have fairly serious limitations, so unless you are <br>

     already using them, I suggest that you avoid them. <br>

  <br>

2.9 - How can I debug my Winsock program? <br>

  <br>

     There are three ways, one of which usually doesn't work. That way is the SOO_DEBUG option, set with setsockopt(). <br>



     I have never tried it on other stacks, but on Microsoft stacks, it is ignorred. I do know that Trumpet Winsock, however, <br>

     offers a fairly decent debugging mode "for free" inside the tcpman tool. Trrumpet (and others) may also support <br>

     SO_DEBUG, though I have been unable to find any information on this. <br>

  <br>

     The second way is to use a network analyzer, colloquially known as a "snifffer," probably due to an early hardware-only <br>

     product by that name. These programs sit on any station on a LAN and, due tto the way typical LANs work, capture all <br>

     of the traffic going over the LAN -- good sniffers will also decode that trraffic by various degrees. One advantage of a <br>

     sniffer is that it literally sees everything about the conversation, includding low level protocol details that aren't available <br>

     from the Winsock layer. Another is that the good ones are extremely powerfuul and configurable. For example, some <br>

     allow you to write "protocol plugins" that will decode any protocol (such aas a custom protocol that you've developed). <br>

  <br>

     The disadvantages of sniffers are several. First, software critics call a ssniffer "inexpensive" when it costs less than $2000, <br>

     and they positively gush when they cost less than $1000. (This is because tthe original sniffers were very expensive pieces <br>

     of dedicated hardware; the Sniffer hardware analyzer from Network General ccosts about $15,000, for example.) There <br>

     are a few truly inexpensive ones, but they all have serious limitations: soome just dump the data raw to disk, others run <br>

     only under uncommon operating systems like DOS and UNIX, and still others aare just plain weak. Another problem with <br>

     sniffers is that the packets must travel over a LAN before they can capturee them -- many sniffers won't work on a <br>

     machine connected through PPP. <br>

  <br>

     All that aside, however, sometimes a sniffer is the only way to find out whhat you want to know about your program's <br>

     behavior. If you've got the cash, a good sniffer is almost always the best tool for the job. <br>

  <br>

  <br>

     The third method is something I call a "Winsock shim." A shim sits between your program and Winsock, either by <br>

     replacing the DLL itself with a proxy DLL, or by "hooking" the Winsock DLL''s API. These tools are limited to <br>

     monitoring events on the Winsock layer itself, and can only monitor a singlle network conversation. Their advantages are <br>

     that this is usually sufficient, and that the most expensive shims cost lesss than $200. <br>

  <br>

     The Resources page has links to several good sniffers and shims. <br>

  <br>

2.10 - How do I get a readable error message from a Winsock error number? <br>

  <br>

     There are a number of ways, but keep in mind that you are best off creatingg your own error messages. Only you can <br>

     decide on proper error messages, because some error values occur in a greatt variety of situations. For example, <br>

     WSAEFAULT could mean "bad pointer passed," or "passed buffer too small," orr even "That version of the API is not <br>

     supported." The Winsock spec does document the most likely error values thaat a given API will return, which you can <br>

     use in constructing your error handlers. <br>

  <br>

     Still, sometimes an API call returns something unexpected, so a cryptic errror message is better than none at all. In that <br>

     case, you can use one of the two following methods: an RC file for Winsock 1.1 messages, or the FormatMessage API <br>

     in Win32. (I have not successfully used FormatMessage for this, but some saay it works. Caveat hacker.) <br>

  <br>

2.11 - Winsock keeps returning the error WSAEWOULDBLOCK. What's wrong with my <br>

program? <br>

  <br>

  <br>

     Not a thing. WSAEWOULDBLOCK is a perfectly normal occurrence in programs ussing non-blocking and <br>

     asynchronous sockets. It's Winsock's way of telling your program "I can't ddo that right now, because I would have to <br>

     block to do so." <br>

  <br>

     The next question is, how do you know when it's safe to try again? In the ccase of asynchronous sockets, Winsock will <br>

     send you an FD_WRITE message after a failed send() call when it is safe to write; it will send you an FD_READ <br>

     message when it is safe to read after a failed recv() call. Similarly, in aa non-blocking sockets program that uses <br>

     select(), the "writefds" will be set when it's okay to write, and the "readdfds" will be set if there is data to read. <br>

  <br>

2.12 - Winsock keeps corrupting my data; I thought TCP was supposed to be reliabble! <br>

  <br>

     This problem is sometimes voiced, "My client program sent 100 bytes, but thhe server program only got 50. What gives?" <br>

     Both these questions indicate a misunderstanding of how TCP works. (I'm nott disparaging anyone here -- I had these <br>

     misconceptions once, too. I think this issue is one of TCP/IP's rites of paassage.) <br>

  <br>

     The critical issue is that TCP is a stream protocol. This means that if youu send 100 bytes, the receiving end could receive <br>

     all 100 bytes at once, or 100 separate 1-byte chunks, or four 25-byte chunkks. Or, the receiver could even receive that <br>

     100 byte block plus some data from the previous send and some from the succceeding send. Re-read this paragraph until <br>

     you truly understand it. I'm not kidding. <br>

  <br>

     "Okay, so now that I understand stream protocols, what do I do if I want thhe receiving end to read whole packets only?" <br>

     you ask. The two most common ways are to either prefix the packet with a leength value, or terminate it with something <br>



     unique. (For what it's worth, a prefix is most helpful if it is a binary-enncoded number; see Question 2.13 for more on this <br>

     subject.) For example, you could create your protocol such that every packeet is preceded by a 2-byte short integer that <br>

     tells how long the packet is. An example of the other method would be a CRLLF (carriage return, line feed) as used in the <br>

     NNTP, POP3, SMTP and HTTP protocols. I prefer the former method, because thhe latter requires your program to <br>

     blindly read until it finds the end of the packet, whereas the former lets the program start dealing with the packet just as <br>

     soon as the length prefix comes in. <br>

  <br>

     In any case, the most important thing is to check the return value of recv((), which indicates how many bytes it placed in <br>

     your buffer. Between this and your new packet-finding code, you should be aable to reliably read complete packets from <br>

     the TCP stream. <br>

  <br>

2.13 - I've read Question 2.12, and that's not the problem. Have any more brightt ideas? <br>

  <br>

     Another possible problem, if your program is talking to one on another plattform, is the byte order of integers. You have <br>

     probably noticed all that ntohs() and htonl() stuff required in Winsock proogramming, but you might not know why <br>

     it's required. The reason is that there are two major ways of storing integgers on a computer: big-endian and little-endian. <br>

     Big-endian numbers are stored with the most significant byte in the lowest memory location ("big-end first"), whereas <br>

     little-endian systems reverse this. (There are even bizarre "middle-endian"" systems!) Obviously two computers must <br>

     agree on a common number format if they are to communicate, so TCP/IP speciifies that the headers use "network byte <br>

     order." <br>

  <br>

     The end result is, if you are sending bare integers as part of your networkk protocol, and the receiving end is on a platform <br>

     The end result is, if you are sending bare integers as part of your networkk protocol, and the receiving end is on a platform <br>

     that uses a different integer representation, it will perceive the data as garbled. To fix this, follow the lead of the TCP <br>

     protocol and use network byte order, always. <br>

  <br>

     For what it's worth, network byte order is big-endian, though you should neever take advantage of this fact. Some <br>

     programmers working on big-endian machines ignore byte ordering issues, butt this is bad style, if for no other reason than <br>

     because it creates bad habits that can bite you later. <br>

  <br>

     Other interesting trivia: the most common little-endian machines are the Inntel x86 and the Digital Alpha; most everything <br>

     else, including the Motorola 680x0, the Sun SPARC and the MIPS Rx000, are bbig-endian. Oddly enough, there are a <br>

     few "bi-endian" devices that can operate in either mode, like the PowerPC aand the HP PA-RISC 8000. Most <br>

     PowerPCs always run in big-endian mode, however, and I suspect that the samme is true of the PA-RISC. <br>

  <br>

v-- <br>

人生在世,如果不能喝酒,不能想女人,连人家欺负到了头上也不能还手,还不如死了算了了  <br>

  <br>

※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.74.189] <br>

发信人: Christopher (Chris), 信区: Winsock <br>

标  题: Re: 一个不错的Winsocket站点 <br>

发信站: BBS 水木清华站 (Fri Feb 27 10:12:17 1998) <br>

  <br>

【 在 Christopher (Chris) 的大作中提到: 】 <br>

第三部分,建议用WWW浏览。 <br>



Section 3 - Advanced Issues <br>

  <br>

3.1 - How can I open a raw data socket? <br>

  <br>

     Under Winsock 1.1, the SOCK_RAW socket type is optional. Many major Winsockk vendors implement it, but <br>

     Microsoft's stacks do not. <br>

  <br>

     SOCK_RAW was not mandated in Winsock 1.1 because: 1) not every stack vendorr can supply a complete <br>

     SOCK_RAW interface, and 2) the Winsock spec's writers decided not to mess wwith the problem of how "raw" a <br>

     SOCK_RAW connection should be. Since the spec does not enlighten us as to wwhat we should expect from a <br>

     SOCK_RAW implementation, it is hard to give examples of "proper" use. <br>

  <br>

     The Winsock 2 spec gives more details about raw sockets, and Microsoft's Wiinsock 2 stacks do implement some types <br>

     of raw sockets. Unfortunately, this support is fairly sparse. So far as I ccan tell, Microsoft only supports raw IGMP and <br>

     ICMP sockets, the latter so that programs can send "ping" packets. (See thee raw sockets ping example for an program <br>

     that uses this functionality.) Microsoft stacks do not support raw IP or "ppacket capturing" from the Winsock layer, <br>

     supposedly so people can't write IP spoofing programs and packet sniffers. This is somewhat understandable given that <br>

     Windows 95 has essentially no security, so you couldn't do things like lockk out raw sockets for unprivlegded users. (See <br>

     Questions 3.13 and 3.14 for more information.) <br>

  <br>

     Other Winsocks may provide more raw sockets capabilities, but keep in mind that using this support might tie your <br>

     program to their particular Winsock implementation. <br>



  <br>

3.2 - How can I "ping" another machine with Winsock? <br>

  <br>

     The "official" method uses the IPPROTO_ICMP raw socket type defined by Winssock 2. I have tested this method <br>

     under Windows NT 4.0, and it works well. Reports indicate that it works undder Windows 95 with the Winsock 2 SDK <br>

     as well. Note that this code might actually work under some non-Microsoft WWinsock 1.1 stacks, but I have heard no <br>

     such reports. [C++ example] <br>

  <br>

     The other method uses ICMP.DLL, which is an extension specific to Microsoftt stacks. While it does currently work, <br>

     Microsoft discourages its use in the strongest terms possible, claiming thaat the API will disappear as soon as a better <br>

     method exists. (I am guessing that this refers to the deployment of Windowss 98, which will have Winsock 2's raw <br>

     sockets support.) Its main advantage is that it works under Winsock 1.1, whhile the above method generally does not. <br>

     [C++ example] <br>

  <br>

     I want to point out that if your program needs to ping another machine, it can simply be the result of a poorly-designed <br>

     protocol, rather than an actual need. Granted, it can be used to provide moore effective feedback in your program, but <br>

     you shouldn't rely on it for issues like connection checking. For example, I'm always seeing people ask about pinging <br>

     when what they really want is to use asynchronous sockets, so they can moniitor the FD_CLOSE event. (See Tutorial 1 <br>

     for more ranting about blocking sockets and such.) <br>

  <br>

3.3 - How do I share a socket between two processes? <br>

  <br>

  <br>

     This is not possible under Winsock 1.1, because it wasn't considered sufficciently important at the time the spec was <br>

     created. <br>

  <br>

     Winsock 2, however, does provide support for this through the WSADuplicateSSocket() facility. The spec describes <br>

     this method in more detail. Another interesting source of information aboutt this is Microsoft Knowledge Base article <br>

     Q150523, which describes the difference between socket inheritance between Windows 95 and Windows NT. <br>

  <br>

3.4 - Why is ioctlsocket() so crippled compared to UNIX ioctl()? <br>

  <br>

     Probably for portability reasons. Keep in mind that Winsock was an after-thhe-fact specification when it was first created; <br>

     that is, it tried to provide a BSD sockets-like interface for common Windowws network stacks. So, many of the familiar <br>

     SIOC* and FIO* parameters were left out because there was no simple way to implement them on the existing stacks. <br>

     Also, unlike Winsock's ioctlsocket(), BSD's ioctl() call controls more thann socket descriptors. <br>

  <br>

     There are two possible ways to get more functionality. The first is vendor support. Some Winsock vendors may provide <br>

     support for the more advanced ioctl() parameters. (This is less likely in ttoday's Microsoft-dominated Winsock world <br>

     than it was in the past, when Microsoft's Winsock offerings were either nonnexistent or weak.) The other is Winsock 2, <br>

     which offers a number of new options. The new options mainly center around new Winsock 2 features like Quality of <br>

     Service and Multicasting, but a few new general-use items have been added, like getting information about the <br>

     computer's network interfaces. Also, since file and socket descriptors are equivalent under Winsock 2, the Win32 API <br>

     might actually provide the behavior you want among its I/O APIs. <br>

  <br>

  <br>

3.5 - How can I get the local user name? <br>

  <br>

     There are a few ways. The easiest is to use the Win32 call GetUserName(). [[C++ Example]. <br>

  <br>

     The other way is shown in the Microsoft Knowledge Base article Q155698 ("Hoow To Look Up Current User Name <br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -