📄 44.htm
字号:
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 + -