• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            山寨:不是最好的,是最適合我們的!歡迎體驗山寨 中文版MSDN

            Blog @ Blog

            當華美的葉片落盡,生命的脈絡才歷歷可見。 -- 聶魯達

            常用鏈接

            統計

            積分與排名

            BBS

            Blog

            Web

            最新評論

            isabc 或 www.isabc.com
            m_ctrlIP.SetWindowText(strTemp);
            re: 數據結構復習筆記 isabc 2008-11-27 17:51
            關于圖、排序和查找在后續會補上!
            現象:
            當你編譯一個ATL工程的Release版時,你得到了下面這個鏈接錯誤:

            LIBCMT.LIB(crt0.obj) : error LNK2001: unresolved external symbol _main

            如下圖所示:


            而Debug版本的編連卻順利通過。




            原因與解決方法:
            出錯原因:
            如果你在工程中使用了CRT函數,而這些函數又需要CRT啟動代碼,就會出現這種鏈接錯誤。默認情況下,Release配置的Preprocessor definitions中定義了_ATL_MIN_CRT,它將CRT啟動代碼從你的EXE或DLL剔出去了。




            背景知識:
            1:

            ATL支持把一個服務器編連優化成最小尺寸或者依賴性最小。我們可以定義三個預處理器符號來影響服務器的優化。

            _ATL_MIN_CRT 服務器不鏈接標準的C/C++運行庫

            _ATL_DLL 服務器動態鏈接工具函數庫atl.dll

            _ATL_STATIC_REGISTRY 服務器靜態鏈接對組件注冊的支持

            如果定義了預處理器符號_ATL_MIN_CRT,那么我們的服務器不鏈接C/C++運行庫,并且ATL提供了函數malloc、realloc、new和delete的一個實現。當定義了這個符號時,我們不能調用任何其他的C/C++運行庫的函數。否則,就會受到這樣的待遇:

            LIBCMT.LIB(crt0.obj) : error LNK2001: unresolved external symbol _main

            ATL向導生成的ATL工程為所有的Release版本的編連定義了_ATL_MIN_CRT,但是沒有為Debug版本定義這個符號。

            Debug配置沒有定義這三個符號中的任何一個。

            RelMinSize配置定義了_ATL_MIN_CRT和_ATL_DLL。

            RelMinDependency配置定義了_ATL_MIN_CRT和_ATL_STATIC_REGISTRY。



            2:

            C Run-Time Library (without iostream)
            Characteristics
            Option
            Defined

            LIBC.LIB
            a statically linked library for single-threaded programs

            (Single threaded, static link)
            /ML


            LIBCMT.LIB
            a statically linked library that supports multithreaded programs

            (Multithreaded, static link)
            /MT
            _MT

            MSVCRT.LIB
            Multithreaded, dynamic link (import library for MSVCRT.DLL)
            /MD
            _MT, _DLL




            解決方法:


            下面方法中的任何一個都可以糾正這個錯誤:

            Ø 去除_ATL_MIN_CRT這個預處理符號;

            Ø 打開stdafx.cpp,注釋掉#include <atlimpl.cpp>這句話,然后編譯,即可;

            Ø 在工程的配置對話框的Link頁面上,"ignore libraries"編輯框中輸入Libcmt.lib,然后編譯,如下圖所示:


            你將會得到幾個“unresolved external”的錯誤,如下所示。


            這個列表就是你用到的CRT的函數。

            Look for things that you think may be pulling in the startup code and remove them if you can.Instead, use their Win32 equivalents. For example, use lstrcmp() instead of strcmp(). Known functions that require CRT startup code are some of the string and floating point functions.

            其他:
            我的VC IDE是6.0版本和SP5,如果用ATL COM AppWizard創建Service (EXE)工程。在這種情況下,它的RelMinDependency版本的配置中就沒有定義_ATL_MIN_CRT符號!這和微軟聲稱的“Service EXE Created with ATL COM AppWizard Doesn't Build in Release Mode”不一樣,可能這是一個已經被FIX了的Bug。





            Written by zhengyun



            參考文獻:

            1. 《INFO: Active Template Library (ATL) 2.0 Readme File [Q165259]》

            2. 《INFO: LNK2001 on CRT Symbols in ATL Release Build [Q165076]》



            謝謝!@fly931
            謝謝你!你說的校驗碼是目前我數據區的最后2個字節還是最前面2個字節!@zongzw
            re: vc里如何調用存儲過程 isabc 2008-06-17 23:24
            http://topic.csdn.net/t/20060724/19/4901741.html VC中如何調用存儲過程???急救!!!

            http://www.poptool.net/software/p5/A5609.shtml vc怎樣調用存儲過程?

            http://topic.csdn.net/t/20030925/15/2299494.html VC如何調用存儲過程

            http://www.80diy.com/home/20001129/10/43596.html 誰知道VC如何調用SQL Server 的存儲過程?
            re: vc picture控件使用 isabc 2008-06-16 16:08
            在以前版本的Windows 98/2000中,集成了柯達公司的圖像處理程序,但從Windows XP開始微軟將其丟了出去,換成了“Windows圖片和傳真查看器”,如果你想找回原來的圖像處理程序,那么首先要準備Windows 2000安裝光盤,然后從中復制以下文件:OCKODAK.DLL、OIENG400.DLL、OIPRT400.DLL、OISLB400.DLL、OISSQ400.DLL、OITWA400.DLL、OIUI400.DLL、IMGCMN.DLL、IMGADMIN.OCX、IMGEDIT.OCX、IMGSCAN.OCX、IMGTHUMB.OCX,需要注意的是,這些文件可能被壓縮為“**_”格式,你可以使用WinZip進行解壓縮。
            如果只有Windows 98安裝光盤,那么除復制上述文件外,還要復制OIADM400.DLL、OICOM400.DLL、OIDIS400.DLL、OIFIL400.DLL、 OIGFS400.DLL、IMGSHL.DLL、IMGOCXD.HLP,并將它們放置到Windows\System32文件夾中。
            接下來就要注冊那些OCX文件,按下Win+R組合鍵打開“運行”窗口,輸入:regsvr32 imgadmin.ocx,同樣方法注冊imgedit.ocx、imgscan.ocx和imgthumb.ocx,接下來就可以運行柯達圖像處理工具。
            re: 結構體對齊問題 isabc 2008-05-25 21:51
            #pragma pack(push)
            #pragma pack(1)
            typedef struct arp_header{
            //-----------------------DLC Header----------------------------------------
            unsigned char DesMAC[6]; //目標MAC
            unsigned char SrcMAC[6]; //源MAC
            unsigned short EtherType; //EtherType默認為0x0806是ARP幀的類型值
            //-----------------------ARP Frame-----------------------------------------
            unsigned short HW_Type; //硬件類型
            unsigned short Prot_Type; //上層協議類型
            unsigned char HW_Addr_Len; //MAC地址長度
            unsigned char Prot_Addr_Len; //IP地址類型
            unsigned short Opcode; //操作碼 0x01表示ARP請求包 0x02表示RARP應答包

            unsigned char Send_MAC_Addr[6]; //發送方MAC
            unsigned long Send_IP_Addr; //發送方IP
            unsigned char Targ_MAC_Addr[6];//接收方MAC
            unsigned long arg_IP_Addr; //接受方IP
            unsigned char padding[18]; //填充數據
            }ARPHEADER,*PARPHEADER;
            #pragma pack(pop)
            謝謝你的關注,上周我只是在BLOG中保存這些數據,今晚抽時間分析了下,如果有什么不對或者好的建議歡迎提出!謝謝@true
            VC++ Combo Box/Combo Box Ex控件
              組合窗口是由一個輸入框和一個列表框組成。創建一個組合窗口可以使用成員函數:
            BOOL CListBox::Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff );
            其中dwStyle將指明該窗口的風格,除了子窗口常用的風格WS_CHILD,WS_VISIBLE外,你可以針對列表控件指明專門的風格。
            CBS_DROPDOWN 下拉式組合框
            CBS_DROPDOWNLIST 下拉式組合框,但是輸入框內不能進行輸入
            CBS_SIMPLE 輸入框和列表框同時被顯示
            LBS_SORT 所有的行按照字母順序進行排序

            由于組合框內包含了列表框,所以列表框的功能都能夠使用,如可以利用:
            int AddString( LPCTSTR lpszItem )添加行,
            int DeleteString( UINT nIndex )刪除指定行,
            int InsertString( int nIndex, LPCTSTR lpszItem )將行插入到指定位置。
            void ResetContent( )可以刪除列表框中所有行。
            通過調用int GetCount( )得到當前列表框中行的數量。

            如果需要得到/設置當前被選中的行的位置,可以調用int GetCurSel( )/int SetCurSel(int iIndex)。通過調用int GetLBText( int nIndex, LPTSTR lpszText )得到列表框內指定行的字符串。

            此外通過調用int FindString( int nStartAfter, LPCTSTR lpszItem )可以在當前所有行中查找指定的字符傳的位置,nStartAfter指明從那一行開始進行查找。
            int SelectString( int nStartAfter, LPCTSTR lpszItem )可以選中包含指定字符串的行。

            此外輸入框的功能都能夠使用,如可以利用:
            DWORD GetEditSel( ) /BOOL SetEditSel( int nStartChar, int nEndChar )得到或設置輸入框中被選中的字符位置。

            BOOL LimitText( int nMaxChars )設置輸入框中可輸入的最大字符數。
            輸入框的剪貼板功能Copy,Clear,Cut,Paste動可以使用。

            最后介紹一下列表框幾種常用的消息映射宏:

            ON_CBN_DBLCLK 鼠標雙擊
            ON_CBN_DROPDOWN 列表框被彈出
            ON_CBN_KILLFOCUS / ON_CBN_SETFOCUS 在輸入框失去/得到輸入焦點時產生
            ON_CBN_SELCHANGE 列表框中選擇的行發生改變
            ON_CBN_EDITUPDATE 輸入框中內容被更新
            使用以上幾種消息映射的方法為定義原型如:afx_msg void memberFxn( );的函數,并且定義形式如ON_Notification( id, memberFxn )的消息映射。如果在對話框中使用組合框,Class Wizard會自動列出相關的消息,并能自動產生消息映射代碼。

            在MFC 4.2中對組合框進行了增強,你可以在組合框中使用ImageList,有一個新的類CComboBoxEx(由CComboBox派生)來實現這一功能。在CComboBoxEx類中添加了一些新的成員函數來實現新的功能:首先你需要調用CImageList* SetImageList( CImageList* pImageList );來設置ImageList,然后調用
            int InsertItem( const COMBOBOXEXITEM* pCBItem );來添加行,其中COMBOBOXEXITEM定義如下:
            typedef struct {       UINT mask;       int iItem;       LPTSTR pszText;      int cchTextMax;       int iImage;       int iSelectedImage;      int iOverlay;       int iIndent;       LPARAM lParam;} COMBOBOXEXITEM, *PCOMBOBOXEXITEM;
            你需要設置mask=CBEIF_IMAGE CBEIF_TEXT,并設置iItem為插入位置,設置pszText為顯示字符串,設置iImage為顯示的圖標索引。下面的代碼演示了如何進行插入:

            /*m_cbeWnd 為已經創建的CComboBox對象
            m_list 為CImageList對象IDB_IMG 為16*(16*4)的位圖,每個圖片為16*16共4個圖標*/
            m_list.Create(IDB_IMG,16,4,RGB(0,0,0));
            m_cbeWnd.SetImageList(&m_list);
            COMBOBOXEXITEM insItem;insItem.mask=CBEIF_IMAGE CBEIF_TEXT;insItem.iItem=0; insItem.iImage=0;insItem.pszText="Line 1";m_cbeWnd.InsertItem(&insItem);insItem.iItem=1;insItem.iImage=1;insItem.pszText="Line 2";m_cbeWnd.InsertItem(&insItem);
            通過調用int DeleteItem( int iIndex );來刪除行,并指明行的位置。
            通過調用BOOL GetItem( COMBOBOXEXITEM* pCBItem )/BOOL SetItem( const COMBOBOXEXITEM* pCBItem );來得到/設置行數據。
            控制Combo Box的下拉長度
            1,首先要知道兩點:一、那就是在設計界面里,點擊一下Combo Box的下拉箭頭,此時出現的調整框就是Combo Box的下拉調整框。
            二、屬性里有個 No integral height 鉤選項,表示最大長度為設計長度,如果實際內容比設計長度多,就出現滾動條,少就以實際長度顯示。
            Network Working Group K. Egevang
            Request for Comments: 1631 Cray Communications
            Category: Informational P. Francis
            NTT
            May 1994

            The IP Network Address Translator (NAT)

            Status of this Memo

            This memo provides information for the Internet community. This memo
            does not specify an Internet standard of any kind. Distribution of
            this memo is unlimited.

            Abstract

            The two most compelling problems facing the IP Internet are IP
            address depletion and scaling in routing. Long-term and short-term
            solutions to these problems are being developed. The short-term
            solution is CIDR (Classless InterDomain Routing). The long-term
            solutions consist of various proposals for new internet protocols
            with larger addresses.

            It is possible that CIDR will not be adequate to maintain the IP
            Internet until the long-term solutions are in place. This memo
            proposes another short-term solution, address reuse, that complements
            CIDR or even makes it unnecessary. The address reuse solution is to
            place Network Address Translators (NAT) at the borders of stub
            domains. Each NAT box has a table consisting of pairs of local IP
            addresses and globally unique addresses. The IP addresses inside the
            stub domain are not globally unique. They are reused in other
            domains, thus solving the address depletion problem. The globally
            unique IP addresses are assigned according to current CIDR address
            allocation schemes. CIDR solves the scaling problem. The main
            advantage of NAT is that it can be installed without changes to
            routers or hosts. This memo presents a preliminary design for NAT,
            and discusses its pros and cons.

            Acknowledgments

            This memo is based on a paper by Paul Francis (formerly Tsuchiya) and
            Tony Eng, published in Computer Communication Review, January 1993.
            Paul had the concept of address reuse from Van Jacobson.

            Kjeld Borch Egevang edited the paper to produce this memo and
            introduced adjustment of sequence-numbers for FTP. Thanks to Jacob
            Michael Christensen for his comments on the idea and text (we thought

            for a long time, we were the only ones who had had the idea).

            1. Introduction

            The two most compelling problems facing the IP Internet are IP
            address depletion and scaling in routing. Long-term and short-term
            solutions to these problems are being developed. The short-term
            solution is CIDR (Classless InterDomain Routing) [2]. The long-term
            solutions consist of various proposals for new internet protocols
            with larger addresses.

            Until the long-term solutions are ready an easy way to hold down the
            demand for IP addresses is through address reuse. This solution takes
            advantage of the fact that a very small percentage of hosts in a stub
            domain are communicating outside of the domain at any given time. (A
            stub domain is a domain, such as a corporate network, that only
            handles traffic originated or destined to hosts in the domain).
            Indeed, many (if not most) hosts never communicate outside of their
            stub domain. Because of this, only a subset of the IP addresses
            inside a stub domain, need be translated into IP addresses that are
            globally unique when outside communications is required.

            This solution has the disadvantage of taking away the end-to-end
            significance of an IP address, and making up for it with increased
            state in the network. There are various work-arounds that minimize
            the potential pitfalls of this. Indeed, connection-oriented protocols
            are essentially doing address reuse at every hop.

            The huge advantage of this approach is that it can be installed
            incrementally, without changes to either hosts or routers. (A few
            unusual applications may require changes). As such, this solution can
            be implemented and experimented with quickly. If nothing else, this
            solution can serve to provide temporarily relief while other, more
            complex and far-reaching solutions are worked out.

            2. Overview of NAT

            The design presented in this memo is called NAT, for Network Address
            Translator. NAT is a router function that can be configured as shown
            in figure 1. Only the stub border router requires modifications.

            NAT's basic operation is as follows. The addresses inside a stub
            domain can be reused by any other stub domain. For instance, a single
            Class A address could be used by many stub domains. At each exit
            point between a stub domain and backbone, NAT is installed. If there
            is more than one exit point it is of great importance that each NAT
            has the same translation table.

            \ | / . /
            +---------------+ WAN . +-----------------+/
            |Regional Router|----------------------|Stub Router w/NAT|---
            +---------------+ . +-----------------+\
            . | \
            . | LAN
            . ---------------
            Stub border

            Figure 1: NAT Configuration

            For instance, in the example of figure 2, both stubs A and B
            internally use class A address 10.0.0.0. Stub A's NAT is assigned the
            class C address 198.76.29.0, and Stub B's NAT is assigned the class C
            address 198.76.28.0. The class C addresses are globally unique no
            other NAT boxes can use them.

            \ | /
            +---------------+
            |Regional Router|
            +---------------+
            WAN | | WAN
            | |
            Stub A .............|.... ....|............ Stub B
            | |
            {s=198.76.29.7,^ | | v{s=198.76.29.7,
            d=198.76.28.4}^ | | v d=198.76.28.4}
            +-----------------+ +-----------------+
            |Stub Router w/NAT| |Stub Router w/NAT|
            +-----------------+ +-----------------+
            | |
            | LAN LAN |
            ------------- -------------
            | |
            {s=10.33.96.5, ^ | | v{s=198.76.29.7,
            d=198.76.28.4}^ +--+ +--+ v d=10.81.13.22}
            |--| |--|
            /____\ /____\
            10.33.96.5 10.81.13.22

            Figure 2: Basic NAT Operation

            When stub A host 10.33.96.5 wishes to send a packet to stub B host
            10.81.13.22, it uses the globally unique address 198.76.28.4 as
            destination, and sends the packet to it's primary router. The stub
            router has a static route for net 198.76.0.0 so the packet is
            forwarded to the WAN-link. However, NAT translates the source address
            10.33.96.5 of the IP header with the globally unique 198.76.29.7

            before the package is forwarded. Likewise, IP packets on the return
            path go through similar address translations.

            Notice that this requires no changes to hosts or routers. For
            instance, as far as the stub A host is concerned, 198.76.28.4 is the
            address used by the host in stub B. The address translations are
            completely transparent.

            Of course, this is just a simple example. There are numerous issues
            to be explored. In the next section, we discuss various aspects of
            NAT.

            3. Various Aspects of NAT

            3.1 Address Spaces

            Partitioning of Reusable and Non-reusable Addresses

            For NAT to operate properly, it is necessary to partition the IP
            address space into two parts - the reusable addresses used internal
            to stub domains, and the globally unique addresses. We call the
            reusable address local addresses, and the globally unique addresses
            global addresses. Any given address must either be a local address or
            a global address. There is no overlap.

            The problem with overlap is the following. Say a host in stub A
            wished to send packets to a host in stub B, but the local addresses
            of stub B overlapped the local addressees of stub A. In this case,
            the routers in stub A would not be able to distinguish the global
            address of stub B from its own local addresses.

            Initial Assignment of Local and Global Addresses

            A single class A address should be allocated for local networks. (See
            RFC1597 [3].) This address could then be used for internets with no
            connection to the Internet. NAT then provides an easy way to change
            an experimental network to a "real" network by translating the
            experimental addresses to globally unique Internet addresses.

            Existing stubs which have unique addresses assigned internally, but
            are running out of them, can change addresses subnet by subnet to
            local addresses. The freed adresses can then be used by NAT for
            external communications.

            3.2 Routing Across NAT

            The router running NAT should never advertise the local networks to
            the backbone. Only the networks with global addresses may be known
            outside the stub. However, global information that NAT receives from
            the stub border router can be advertised in the stub the usual way.

            Private Networks that Span Backbones

            In many cases, a private network (such as a corporate network) will
            be spread over different locations and will use a public backbone for
            communications between those locations. In this case, it is not
            desirable to do address translation, both because large numbers of
            hosts may want to communicate across the backbone, thus requiring
            large address tables, and because there will be more applications
            that depend on configured addresses, as opposed to going to a name
            server. We call such a private network a backbone-partitioned stub.

            Backbone-partitioned stubs should behave as though they were a non-
            partitioned stub. That is, the routers in all partitions should
            maintain routes to the local address spaces of all partitions. Of
            course, the (public) backbones do not maintain routes to any local
            addresses. Therefore, the border routers must tunnel through the
            backbones using encapsulation. To do this, each NAT box will set
            aside one global address for tunneling. When a NAT box x in stub
            partition X wishes to deliver a packet to stub partition Y, it will
            encapsulate the packet in an IP header with destination address set
            to the global address of NAT box y that has been reserved for
            encapsulation. When NAT box y receives a packet with that destination
            address, it decapsulates the IP header and routes the packet
            internally.

            3.3 Header Manipulations

            In addition to modifying the IP address, NAT must modify the IP
            checksum and the TCP checksum. Remember, TCP's checksum also covers a
            pseudo header which contains the source and destination address. NAT
            must also look out for ICMP and FTP and modify the places where the
            IP address appears. There are undoubtedly other places, where
            modifications must be done. Hopefully, most such applications will be
            discovered during experimentation with NAT.

            The checksum modifications to IP and TCP are simple and efficient.
            Since both use a one's complement sum, it is sufficient to calculate
            the arithmetic difference between the before-translation and after-
            translation addresses and add this to the checksum. The only tricky
            part is determining whether the addition resulted in a wrap-around
            (in either the positive or negative direction) of the checksum. If

            so, 1 must be added or subtracted to satisfy the one's complement
            arithmetic. Sample code (in C) for this is as follows:

            void checksumadjust(unsigned char *chksum, unsigned char *optr,
            int olen, unsigned char *nptr, int nlen)
            /* assuming: unsigned char is 8 bits, long is 32 bits.
            - chksum points to the chksum in the packet
            - optr points to the old data in the packet
            - nptr points to the new data in the packet
            */
            {
            long x, old, new;
            x=chksum[0]*256+chksum[1];
            x=~x;
            while (olen) {
            if (olen==1) {
            old=optr[0]*256+optr[1];
            x-=old & 0xff00;
            if (x<=0) { x--; x&=0xffff; }
            break;
            }
            else {
            old=optr[0]*256+optr[1]; optr+=2;
            x-=old & 0xffff;
            if (x<=0) { x--; x&=0xffff; }
            olen-=2;
            }
            }
            while (nlen) {
            if (nlen==1) {
            new=nptr[0]*256+nptr[1];
            x+=new & 0xff00;
            if (x & 0x10000) { x++; x&=0xffff; }
            break;
            }
            else {
            new=nptr[0]*256+nptr[1]; nptr+=2;
            x+=new & 0xffff;
            if (x & 0x10000) { x++; x&=0xffff; }
            nlen-=2;
            }
            }
            x=~x;
            chksum[0]=x/256; chksum[1]=x & 0xff;
            }

            The arguments to the File Transfer Protocol (FTP) PORT command
            include an IP address (in ASCII!). If the IP address in the PORT
            command is local to the stub domain, then NAT must substitute this.
            Because the address is encoded in ASCII, this may result in a change
            in the size of the packet (for instance 10.18.177.42 is 12 ASCII
            characters, while 193.45.228.137 is 14 ASCII characters). If the new
            size is the same as the previous, only the TCP checksum needs
            adjustment (again). If the new size is less than the previous, ASCII
            zeroes may be inserted, but this is not guaranteed to work. If the
            new size is larger than the previous, TCP sequence numbers must be
            changed too.

            A special table is used to correct the TCP sequence and acknowledge
            numbers with source port FTP or destination port FTP. The table
            entries should have source, destination, source port, destination
            port, initial sequence number, delta for sequence numbers and a
            timestamp. New entries are created only when FTP PORT commands are
            seen. The initial sequence numbers are used to find out if the
            sequence number of a packet is before or after the last FTP PORT
            command (delta may be increased for every FTP PORT command). Sequence
            numbers are incremented and acknowledge numbers are decremented. If
            the FIN bit is set in one of the packets, the associated entry may be
            deleted soon after (1 minute should be safe). Entries that have not
            been used for e.g. 24 hours should be safe to delete too.

            The sequence number adjustment must be coded carefully, not to harm
            performance for TCP in general. Of course, if the FTP session is
            encrypted, the PORT command will fail.

            If an ICMP message is passed through NAT, it may require two address
            modifications and three checksum modifications. This is because most
            ICMP messages contain part of the original IP packet in the body.
            Therefore, for NAT to be completely transparent to the host, the IP
            address of the IP header embedded in the data part of the ICMP packet
            must be modified, the checksum field of the same IP header must
            correspondingly be modified, and the ICMP header checksum must be
            modified to reflect the changes to the IP header and checksum in the
            ICMP body. Furthermore, the normal IP header must also be modified as
            already described.

            It is not entirely clear if the IP header information in the ICMP
            part of the body really need to be modified. This depends on whether
            or not any host code actually looks at this IP header information.
            Indeed, it may be useful to provide the exact header seen by the
            router or host that issued the ICMP message to aid in debugging. In
            any event, no modifications are needed for the Echo and Timestamp
            messages, and NAT should never need to handle a Redirect message.

            SNMP messages could be modified, but it is even more dubious than for
            ICMP messages that it will be necessary.

            Applications with IP-address Content

            Any application that carries (and uses) the IP address inside the
            application will not work through NAT unless NAT knows of such
            instances and does the appropriate translation. It is not possible or
            even necessarily desirable for NAT to know of all such applications.
            And, if encryption is used then it is impossible for NAT to make the
            translation.

            It may be possible for such systems to avoid using NAT, if the hosts
            in which they run are assigned global addresses. Whether or not this
            can work depends on the capability of the intra-domain routing
            algorithm and the internal topology. This is because the global
            address must be advertised in the intra-domain routing algorithm.
            With a low-feature routing algorithm like RIP, the host may require
            its own class C address space, that must not only be advertised
            internally but externally as well (thus hurting global scaling). With
            a high-feature routing algorithm like OSPF, the host address can be
            passed around individually, and can come from the NAT table.

            Privacy, Security, and Debugging Considerations

            Unfortunately, NAT reduces the number of options for providing
            security. With NAT, nothing that carries an IP address or information
            derived from an IP address (such as the TCP-header checksum) can be
            encrypted. While most application-level encryption should be ok, this
            prevents encryption of the TCP header.

            On the other hand, NAT itself can be seen as providing a kind of
            privacy mechanism. This comes from the fact that machines on the
            backbone cannot monitor which hosts are sending and receiving traffic
            (assuming of course that the application data is encrypted).

            The same characteristic that enhances privacy potentially makes
            debugging problems (including security violations) more difficult. If
            a host is abusing the Internet is some way (such as trying to attack
            another machine or even sending large amounts of junk mail or
            something) it is more difficult to pinpoint the source of the trouble
            because the IP address of the host is hidden.

            4. Conclusions

            NAT may be a good short term solution to the address depletion and
            scaling problems. This is because it requires very few changes and
            can be installed incrementally. NAT has several negative
            characteristics that make it inappropriate as a long term solution,
            and may make it inappropriate even as a short term solution. Only
            implementation and experimentation will determine its
            appropriateness.

            The negative characteristics are:

            1. It requires a sparse end-to-end traffic matrix. Otherwise, the NAT
            tables will be large, thus giving lower performance. While the
            expectation is that end-to-end traffic matrices are indeed sparse,
            experience with NAT will determine whether or not they are. In any
            event, future applications may require a rich traffic matrix (for
            instance, distributed resource discovery), thus making long-term use
            of NAT unattractive.

            2. It increases the probability of mis-addressing.

            3. It breaks certain applications (or at least makes them more difficult
            to run).

            4. It hides the identity of hosts. While this has the benefit of
            privacy, it is generally a negative effect.

            5. Problems with SNMP, DNS, ... you name it.

            Current Implementations

            Paul and Tony implemented an experimental prototype of NAT on public
            domain KA9Q TCP/IP software [1]. This implementation manipulates
            addresses and IP checksums.

            Kjeld implemented NAT in a Cray Communications IP-router. The
            implementation was tested with Telnet and FTP. This implementation
            manipulates addresses, IP checksums, TCP sequence/acknowledge numbers
            and FTP PORT commands.

            The prototypes has demonstrated that IP addresses can be translated
            transparently to hosts within the limitations described in this
            paper.

            REFERENCES

            [1] Karn, P., "KA9Q", anonymous FTP from ucsd.edu
            (hamradio/packet/ka9q/docs).

            [2] Fuller, V., Li, T., and J. Yu, "Classless Inter-Domain Routing
            (CIDR) an Address Assignment and Aggregation Strategy", RFC1519,
            BARRNet, cisco, Merit, OARnet, September 1993.

            [3] Rekhter, Y., Moskowitz, B., Karrenberg, D., and G. de Groot,
            "Address Allocation for Private Internets", RFC1597, T.J. Watson
            Research Center, IBM Corp., Chrysler Corp., RIPE NCC, March 1994.

            Security Considerations

            Security issues are not discussed in this memo.

            Authors' Addresses

            Kjeld Borch Egevang
            Cray Communications
            Smedeholm 12-14
            DK-2730 Herlev
            Denmark

            Phone: +45 44 53 01 00
            EMail: kbe@craycom.dk

            Paul Francis
            NTT Software Lab
            3-9-11 Midori-cho Musashino-shi
            Tokyo 180 Japan

            Phone: +81-422-59-3843
            Fax +81-422-59-3765
            尋路者(158989725) 16:37:15
            sizeof是編譯時確定的.
            尋路者(158989725) 16:37:28
            strlen是運行時確定的.
            re: 簡單封裝的串口通信類 isabc 2008-01-08 16:58
            查詢當前的超時設置應調用GetCommTimeouts函數,該函數會填充一個COMMTIMEOUTS結構。調用SetCommTimeouts可以用某一個COMMTIMEOUTS結構的內容來設置超時。
              讀寫串口的超時有兩種:間隔超時和總超時。間隔超時是指在接收時兩個字符之間的最大時延。總超時是指讀寫操作總共花費的最大時間。寫操作只支持總超時,而讀操作兩種超時均支持。用COMMTIMEOUTS結構可以規定讀寫操作的超時。
            COMMTIMEOUTS結構的定義為: typedef struct _COMMTIMEOUTS {
            DWORD ReadIntervalTimeout; //讀間隔超時
            DWORD ReadTotalTimeoutMultiplier; //讀時間系數
            DWORD ReadTotalTimeoutConstant; //讀時間常量
            DWORD WriteTotalTimeoutMultiplier; // 寫時間系數
            DWORD WriteTotalTimeoutConstant; //寫時間常量
            } COMMTIMEOUTS,*LPCOMMTIMEOUTS;

            COMMTIMEOUTS結構的成員都以毫秒為單位。總超時的計算公式是:
            總超時=時間系數×要求讀/寫的字符數+時間常量
            例如,要讀入10個字符,那么讀操作的總超時的計算公式為:
            讀總超時=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant
            可以看出:間隔超時和總超時的設置是不相關的,這可以方便通信程序靈活地設置各種超時。

            如果所有寫超時參數均為0,那么就不使用寫超時。如果ReadIntervalTimeout為0,那么就不使用讀間隔超時。如果ReadTotalTimeoutMultiplier 和 ReadTotalTimeoutConstant 都為0,則不使用讀總超時。如果讀間隔超時被設置成MAXDWORD并且讀時間系數和讀時間常量都為0,那么在讀一次輸入緩沖區的內容后讀操作就立即返回,而不管是否讀入了要求的字符。
              在用重疊方式讀寫串口時,雖然ReadFile和WriteFile在完成操作以前就可能返回,但超時仍然是起作用的。在這種情況下,超時規定的是操作的完成時間,而不是ReadFile和WriteFile的返回時間。
            配置串口的示例代碼: SetupComm(hCom,1024,1024); //輸入緩沖區和輸出緩沖區的大小都是1024

            COMMTIMEOUTS TimeOuts;
            //設定讀超時
            TimeOuts.ReadIntervalTimeout=1000;
            TimeOuts.ReadTotalTimeoutMultiplier=500;
            TimeOuts.ReadTotalTimeoutConstant=5000;
            //設定寫超時
            TimeOuts.WriteTotalTimeoutMultiplier=500;
            TimeOuts.WriteTotalTimeoutConstant=2000;
            SetCommTimeouts(hCom,&TimeOuts); //設置超時
            re: 簡單封裝的串口通信類 isabc 2008-01-08 10:09
            HANDLE CreateEvent(
            LPSECURITY_ATTRIBUTES lpEventAttributes,
            // 指定對象的安全描述符,一般設為NULL (安全屬性結構如下)
            BOOL bManualReset, // 指定是否人工重置
            BOOL bInitialState, // 返回的句柄是否可繼承
            LPCTSTR lpName // 對象的名字,用于多進程間共享對象
            );
            返回的為event對象的句柄
            安全屬性結構
            typedef struct _SECURITY_ATTRIBUTES {
            DWORD nLength;
            LPVOID lpSecurityDescriptor;
            BOOL bInheritHandle;
            } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;


            從網上整理的文章,同樣,這只是為了我增加理解記憶而做到得筆記,
            不存在利用價值,純粹是學習和記憶.抄襲也好學習也好只是讓人明
            白道理.主要干活的還是自己的程序.

            I/O設備處理必然讓主程序停下來干等I/O的完成,
            對這個問題有

            方法一:使用另一個線程進行I/O。這個方案可行,但是麻煩。

            方法二:使用overlapped I/O。
            正如書上所說:“overlapped I/O是WIN32的一項技術,
            你可以要求操作系統為你傳送數據,并且在傳送完畢時通知你。
            這項技術使你的程序在I/O進行過程中仍然能夠繼續處理事務。
            事實上,操作系統內部正是以線程來I/O完成overlapped I/O。
            你可以獲得線程的所有利益,而不需付出什么痛苦的代價”。


            怎樣使用overlapped I/O:

            進行I/O操作時,指定overlapped方式
            使用CreateFile (),將其第6個參數指定為FILE_FLAG_OVERLAPPED,
            就是準備使用overlapped的方式構造或打開文件;
            如果采用 overlapped,那么ReadFile()、WriteFile()的第5個參數必須提供一個指針,
            指向一個OVERLAPPED結構。 OVERLAPPED用于記錄了當前正在操作的文件一些相關信息。

            //功能:從指定文件的1500位置讀入300個字節
            int main()
            {
            BOOL rc;
            HANDLE hFile;
            DWORD numread;
            OVERLAPPED overlap;
            char buf[512];
            char szPath=”x:\\xxxx\xxxx”;

            //檢查系統,確定是否支持overlapped,(NT以上操作系統支持OVERLAPPED)
            CheckOsVersion();
            // 以overlapped的方式打開文件
            hFile = CreateFile( szPath,
            GENERIC_READ,
            FILE_SHARE_READ|FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            FILE_FLAG_OVERLAPPED,
            NULL
            );

            // OVERLAPPED結構實始化為0
            memset(&overlap, 0, sizeof(overlap));
            //指定文件位置是1500;
            overlap.Offset = 1500;

            rc = ReadFile(hFile,buf,300,&numread,&overlap);
            //因為是overlapped操作,ReadFile會將讀文件請求放入讀隊列之后立即返回(false),
            //而不會等到文件讀完才返回(true)
            if (rc)
            {
            //文件真是被讀完了,rc為true
            // 或當數據被放入cache中,或操作系統認為它可以很快速地取得數據,rc為true
            }
            else
            {
            if (GetLastError() == ERROR_IO_PENDING)
            {//當錯誤是ERROR_IO_PENDING,那意味著讀文件的操作還在進行中
            //等候,直到文件讀完
            WaitForSingleObject(hFile, INFINITE);
            rc = GetOverlappedResult(hFile,&overlap,&numread,FALSE);
            //上面二條語句完成的功能與下面一條語句的功能等價:
            // GetOverlappedResult(hFile,&overlap,&numread,TRUE);
            }
            else
            {
            //出錯了
            }
            }
            CloseHandle(hFile);
            return EXIT_SUCCESS;
            }

            在實際工作中,若有幾個操作同一個文件時,
            怎么辦?我們可以利用OVERLAPPED結構中提供的event來解決上面遇到的問題。
            注意,你所使用的event對象必須是一個MANUAL型的;否則,可能產生競爭條件。
            原因見書P159。
            int main()
            {
            int i;
            BOOL rc;
            char szPath=”x:\\xxxx\xxxx”;
            // 以overlapped的方式打開文件
            ghFile = CreateFile( szPath,
            GENERIC_READ,
            FILE_SHARE_READ|FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            FILE_FLAG_OVERLAPPED,
            NULL
            );
            for (i=0; i<MAX_REQUESTS; i++)
            {
            //將同一文件按幾個部分按overlapped方式同時讀
            //注意看QueueRequest函數是如何運做的,每次讀16384個塊
            QueueRequest(i, i*16384, READ_SIZE);
            }
            // 等候所有操作結束;
            //隱含條件:當一個操作完成時,其對應的event對象會被激活
            WaitForMultipleObjects(MAX_REQUESTS, ghEvents, TRUE, INFINITE);
            // 收尾操作
            for (i=0; i<MAX_REQUESTS; i++)
            {
            DWORD dwNumread;
            rc = GetOverlappedResult(
            ghFile,
            &gOverlapped[i],
            &dwNumread,
            FALSE
            );
            CloseHandle(gOverlapped[i].hEvent);
            }
            CloseHandle(ghFile);
            return EXIT_SUCCESS;
            }

            //當讀操作完成以后,gOverlapped[nIndex].hEvent會系統被激發
            int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount)
            {
            //構造一個MANUAL型的event對象
            ghEvents[nIndex] = CreateEvent(NULL, TRUE, FALSE, NULL);
            //將此event對象置入OVERLAPPED結構
            gOverlapped[nIndex].hEvent = ghEvents[nIndex];
            gOverlapped[nIndex].Offset = dwLocation;
            for (i=0; i<MAX_TRY_COUNT; i++)
            {
            //文件ghFile唯一
            rc = ReadFile(ghFile, gBuffers[nIndex],&dwNumread,&gOverlapped[nIndex]);
            if (rc)
            return TRUE;
            err = GetLastError();
            if (err == ERROR_IO_PENDING)
            {
            //當錯誤是ERROR_IO_PENDING,那意味著讀文件的操作還在進行中
            return TRUE;
            }
            // 處理一些可恢復的錯誤
            if ( err == ERROR_INVALID_USER_BUFFER ||
            err == ERROR_NOT_ENOUGH_QUOTA ||
            err == ERROR_NOT_ENOUGH_MEMORY )
            {
            sleep(50);
            continue;//重試
            }
            // 如果GetLastError()返回的不是以上列出的錯誤,放棄
            break;
            }

            return -1;

            }

            re: 簡單封裝的串口通信類 isabc 2008-01-07 21:11
            在C語言中格式化字符串可以使用printf
            但是在WINDOWS編程設計中卻行不通了,但是卻有變通的方法
            那就是用 wsprintf這個函數 它的格式如下:
            wsprintf(緩沖區,格式,要格式化的值);
            第一個參數是字符緩沖區,后面是格式字符串,wsprintf不是將格式化結果寫到標準輸出,而是將其寫入緩沖區中,該函數返回該字符串的長度。

            比如我們想通過MessageBox來輸出一個整形變量的值,可以用以下代碼實現:

            char szBuffer[100];
            ing number=100;
            wsprintf(szBuffer, “%d”,number);
            MessgaeBox(NULL,szBrffer,TEXT(“格式化字符串”),0);

            這個函數除了將內容格式化輸出到第一個參數所提供的字符串緩沖區以外,其它功能與printf函數相同。

            廣告信息(免費廣告聯系)

            中文版MSDN:
            歡迎體驗

            久久久久女教师免费一区| 午夜天堂av天堂久久久| 久久精品国产黑森林| 久久99这里只有精品国产| 久久亚洲中文字幕精品有坂深雪 | 免费观看久久精彩视频| 91亚洲国产成人久久精品网址| 久久涩综合| 国产亚洲欧美精品久久久| 久久久久久极精品久久久| 亚洲欧美成人综合久久久| 91久久九九无码成人网站| 97精品国产97久久久久久免费| 国内精品久久国产大陆| 久久天天躁夜夜躁狠狠躁2022| 久久99精品久久久久久动态图 | 国产精品久久久久久搜索| 亚洲国产综合久久天堂| 久久精品国产亚洲一区二区| 久久久高清免费视频| 久久国产视屏| 国产真实乱对白精彩久久| 精品久久久久久久无码| 色综合久久久久久久久五月| 久久青青草原亚洲av无码| 国产激情久久久久影院老熟女免费| 久久香蕉国产线看观看猫咪?v| 久久精品国产99久久无毒不卡| 色99久久久久高潮综合影院| a级毛片无码兔费真人久久| 91精品国产高清91久久久久久| 精品国产青草久久久久福利| 久久只这里是精品66| 日韩久久无码免费毛片软件| 久久精品无码av| 久久婷婷五月综合成人D啪| 国产精品内射久久久久欢欢 | 精品多毛少妇人妻AV免费久久| 99久久中文字幕| 曰曰摸天天摸人人看久久久| 久久综合九色综合欧美狠狠|