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

📄 44.htm

📁 网络编程原理文摘 [文件] 精华区目录结构 [目录] 网络编程的基本原理 [目录] 网络编程与网络协议 [目录] 网上资源 [目录] winsock技术 [目录
💻 HTM
📖 第 1 页 / 共 5 页
字号:
     and Domain Name"). It is much more complex, and it shows two completely diffferent methods, one for Windows <br>

     95/Windows 3.1 and one for Windows NT. Unless you need Windows 3.1 support or the LAN Manager domain name <br>

     (as opposed to the DNS domain name), I suggest you give this article a miss <br>

  <br>

3.6 - Is it possible to create sockets that map to a DLL rather than an applicattion? <br>

  <br>

     Under Windows, a DLL's data is actually owned by the application that loadss the DLL. The way to get around this is to <br>

     have your DLL create a "helper process" which will perform all Winsock operrations on behalf of the DLL, because then <br>

     the helper process owns the sockets. <br>

  <br>

3.7 - How do I do a { readv(), fcntl(), etc. } call in my Winsock application? <br>

  <br>

     These calls are BSD sockets calls that didn't make it into Winsock. In geneeral, you will have to code such functions <br>

     yourself, although it would not hurt to suggest them for the next revision of the specification as well. <br>

  <br>

     (Winsock 2 note: The readv() and writev() calls implement scatter/gather I//O with BSD sockets. This functionality is <br>

     available in Winsock 2 with the new WSASend(), WSASendTo(), WSARecv(), and WSARecvFrom() APIs. There are <br>



     probably other BSD-only APIs that are simply provided in a different way unnder Winsock 2 or Win32.) <br>

  <br>

3.8 - How do I get the MAC (a.k.a. hardware) address of the local Ethernet adaptter? <br>

  <br>

     There are two semi-reliable methods, both of which are somewhat kludgey. Thhe first method involves asking the <br>

     NetBIOS API for the adapter addresses. The primary problem with this methodd is that it requires that the Microsoft <br>

     NetBIOS components be installed. <br>

  <br>

     The second method depends on a property of the Remote Procedure Call speciffication that says that the last 6 bytes of a <br>

     UUID will be derived from the hardware address of the local machine's netwoork adapter. In the case of Ethernet (the <br>

     common case), this is the MAC address. The major problem with this method iis that it will only return one address; if <br>

     there is more than one Ethernet network adapter in the system, this method won't let you get that second adapter's <br>

     address. <br>

  <br>

     The descriptions introducing each example go into these issues further. <br>

  <br>

3.9 - In a multithreaded application, can more than one thread access a single ssocket? <br>

  <br>

     Yes. However, keep in mind that Winsock is not thread-safe. For example, iff one thread is interrupted by the operating <br>

     system's scheduler while executing a call to recv() and another thread in tthe same program calls recv() on that same <br>

     socket before the first thread gets control again, havoc will result. <br>

  <br>

  <br>

     If you must let multiple threads access a single socket, you need to carefuully serialize the calls that use it. Unfortunately, I <br>

     cannot say for certain how paranoid you need to be about this. At minimum, you should ensure that no two threads can <br>

     call the same Winsock function on a given socket at the same time. However,, it may be necessary to completely serialize <br>

     every call that uses the socket, so that no two threads can use the same soocket at the same time for anything. <br>

  <br>

3.10 - If two threads in an application call recv() on a socket, will they each get the same data? <br>

  <br>

     No. Winsock does not duplicate data among threads. If you protect your proggram as Question 3.9 recommends, only <br>

     one thread will receive any given piece of data. <br>

  <br>

3.11 - Is there any way for two threads to be notified when something happens onn a socket? <br>

  <br>

     No. If two threads call WSAAsyncSelect() on a single socket, only the threaad that made the last call to <br>

     WSAAsyncSelect() will receive further notification messages. Similarly, if two threads call WSAEventSelect() on a <br>

     socket, only the event object used in the last call will be signalled when an event occurs on that socket. You also can't <br>

     call WSAAsyncSelect() on a socket in one thread and WSAEventSelect() on thaat same socket in another thread, <br>

     because the calls are mutually exclusive for any single socket. Finally, yoou cannot reliably call select() on a single <br>

     socket from two threads and get the same notifications in each, because onee thread could clear or cause an event, which <br>

     would change the events that the other thread sees. <br>

  <br>

3.12 - How do I detect if the modem is connected? <br>

  <br>

  <br>

     Although this is not a Winsock question per se, it is sometimes useful for a Winsock program to only do its thing if the <br>

     computer is already connected to the Internet. Before implementing this, hoowever, keep in mind that many computers are <br>

     not connected to the Internet through a modem. Often, they are connected too a LAN, and that LAN is somehow <br>

     gatewayed to the Internet. For these situations, the following call will foool your program into believing that the user either <br>

     has no Internet connection, or that it is never up. <br>

  <br>

     Having said that, the Remote Access Service (RAS) API gives an application access to the dial-up networking <br>

     subsystem. In particular, the RasEnumConnections() call lets you easily gett a list of the connected modems. <br>

  <br>

3.13 - How can I capture packets on a LAN with Winsock? <br>

  <br>

     You cannot. Winsock (Microsoft Winsock at least) does not allow promiscuouss IP packet captures, unlike, say, most <br>

     versions of UNIX. My personal feeling is that this is probably a good thingg because Windows 95 has essentially no <br>

     security. Since packet capturing is a security hole big enough to drive a DDLT tape through (to mix a metaphor), the only <br>

     solution is to simply not make the feature available. <br>

  <br>

     So how do commercial Ethernet analyzers work, you ask? They talk straight tto the NDIS network driver layer. I am told <br>

     that the Windows NT Device Driver Kit (available with the Professional Leveel of MSDN) comes with a passable start at <br>

     an Ethernet analyzer. Also, PCAUSA sells a package that is supposed to makee writing to the NDIS layer easier. I have, <br>

     however, not tried this product. <br>

  <br>

3.14 - How can I change the IP or TCP header of a packet? <br>



  <br>

     Sorry, that's not possible, because Microsoft Winsocks do not support eitheer raw IP or TCP sockets, or the <br>

     IP_HDRINCL option. A few IP header fields can be set, however, with setsockkopt() and/or ioctl(). One such <br>

     field is TTL. I do not know of any vendor that does offer a stack that suppports raw IP or TCP sockets. <br>

  <br>

3.15 - When should I turn off the Nagle algorithm? <br>

  <br>

     Generally, almost never. <br>

  <br>

     Most people ask this question when they are trying to impose some kind of ""packet" scheme on a TCP data stream, so <br>

     that the receiver gets the packets divided exactly as transmitted. The probblem is, TCP is a stream protocol, and trying to <br>

     fool it into becoming a datagram protocol is simply doomed to fail. There aare a number of reasons for this: <br>

  <br>

        1.If one network host is capable of sending data faster than the other hhost can process it, a backlog will result on the <br>

          slower host. Then, because of the way stream protocols behave, multiplle data packets will be delivered to the <br>

          slower program as a unit, despite the fact that the packets were delivvered to the host with their packet boundary <br>

          intact. <br>

  <br>

        2.Turning off the Nagle algorithm does not work for programs that you doo not control. That is, turning off the Nagle <br>

          algorithm on the client will not affect the way that the server sends packets. <br>

  <br>

        3.Routers and other hardware can fragment packets, and there is no guaraantee of "proper" reassembly with stream <br>



          protocols. Similarly, when sending packets larger than a network mediuum's MTU, fragmentation will result. <br>

  <br>

        4.When a network stack runs out of buffers, it will often fragment a paccket. When this happens, the first N bytes of <br>

          the packet are queued up and the rest discarded, where N is the numberr of bytes remaining in the network stack's <br>

          buffers. In all likelihood, these N bytes will be delivered to the proogram separately from the rest of the packet. <br>

  <br>

     Aside from these problems, disabling the Nagle algorithm almost always causses a program's throughput to degrade. So, <br>

     the only time you should disable the algorithm is when some other consideraation, such as packet timing, is more important <br>

     than throughput. The two canonical examples of good places to disable the NNagle algorithm are in Telnet and the X <br>

     Windows protocol. In the former, the Nagle algorithm is disabled so that thhe user's keystrokes travel immediately to the <br>

     remote host, so as to provide the snappiest possible response. Also, since user input is so slow compared to the <br>

     network's speed, the speed degradation of disabling the algorithm is relatiively unimportant. In implementations of the X <br>

     Windows protocol, the Nagle algorithm is disabled so that mouse movements aare sent immediately; again, the tradeoff is <br>

     "smoothness" and "snap" against network efficiency. <br>

  <br>

     A much better way to impose a "packet" scheme on a stream protocol is to eiither use some form of unique delimiter or a <br>

     length prefix scheme. An example of the former might be separating packets by a caret (^) or a carriage return/line feed <br>

     (CRLF) pair. An example of the latter might be a two-byte integer before evvery packet. I favor the latter, because as <br>

     soon as you read the length prefix, you know how many more bytes to expect.. By contrast, delimiters require that you <br>

     blindly read until you find the end of the packet. Still, both styles are uuseful. <br>

  <br>

-- <br>

-- <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:14:51 1998) <br>

  <br>

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

例程一:得到本机的IP地址。建议用WWW方式浏览。 <br>

  <br>

Example - Getting the Local IP Address <br>

  <br>

This example shows how to get the local machine's IP address(es). Note especiallly the loop near the bottom of the doit() <br>

function. Although the majority of machines have only a single IP address, it iss becoming common for a machine to have two or <br>

more IP addresses. On my home machine, for example, there is one IP address for the Ethernet network board, and one for the <br>

modem when it's connected to my ISP. <br>

  <br>

  <br>

  <br>

getlocalip.cpp <br>

  <br>

// Borland C++ 5.0: bcc32.cpp getlocalip.cpp <br>



// Visual C++ 5.0:  cl getlocalip.cpp wsock32.lib <br>

  <br>

#include <iostream.h> <br>

#include <winsock.h> <br>

  <br>

int doit(int, char**) <br>

{ <br>

    char ac[80]; <br>

    if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) { <br>

        cerr << "Error " << WSAGetLastError() << <br>

                " when getting local host name." << endl; <br>

        return 1; <br>

    } <br>

    cout << "Host name is " << ac << "." << endl; <br>

  <br>

    struct hostent* phe = gethostbyname(ac); <br>

    if (phe == 0) { <br>

        cerr << "Yow!  Bad host lookup." << endl; <br>

        return 1; <br>

    } <br>

  <br>

    for (int i = 0; phe->h_addr_list[i] != 0; ++i) { <br>



        struct in_addr addr; <br>

        memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr)); <br>

        cout << "Address " << i << ": " << inet_ntoa(addr) << endl; <br>

    } <br>

  <br>

    return 0; <br>

} <br>

  <br>

  <br>

int main(int argc, char* argv[]) <br>

{ <br>

    WSAData wsaData; <br>

    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) { <br>

        return 255; <br>

    } <br>

  <br>

    int retval = doit(argc, argv); <br>

⌨️ 快捷键说明

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