• <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>

            興海北路

            ---男兒仗劍自橫行
            <2008年3月>
            2425262728291
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            統(tǒng)計(jì)

            • 隨筆 - 85
            • 文章 - 0
            • 評(píng)論 - 17
            • 引用 - 0

            常用鏈接

            留言簿(6)

            隨筆分類

            隨筆檔案

            收藏夾

            全是知識(shí)啊

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            《windows網(wǎng)絡(luò)編程技術(shù)》之 Winsock基礎(chǔ) - [技術(shù)補(bǔ)鈣]
            轉(zhuǎn)自http://xiekeli.blogbus.com/logs/4019775.html

            前段時(shí)間根據(jù)客服的反映,老翁的前置機(jī)程序存在不工作的情況,初步表現(xiàn)為GPRS登錄失敗,我查看了報(bào)文(強(qiáng)烈要求老板發(fā)獎(jiǎng)金,有什么問(wèn)題我總 是沖鋒在前)發(fā)現(xiàn)基本出現(xiàn)在網(wǎng)絡(luò)頻繁斷開(kāi)的情況后(網(wǎng)絡(luò)每隔10分鐘被斷開(kāi)一次,socket錯(cuò)誤10053,什么原因還不得而知)。忘了說(shuō)了,前置機(jī)是 通過(guò)TCP連接到省局的GPRS代理服務(wù)器(是由小賴開(kāi)發(fā)的)然后和現(xiàn)場(chǎng)的終端進(jìn)行通信。前置機(jī)程序中是通過(guò)delphi的clientsocket進(jìn)行 連接的。一下子還真不知道是什么原因。對(duì)于socket這塊我絕對(duì)不是專家,知其然,不知其所以然。于是我決定先從清理基本概念開(kāi)始:
            鳥(niǎo)瞰TCP/IP體系結(jié)構(gòu) 
            首先從TCP/IP體系結(jié)構(gòu)開(kāi)始(這也是不少公司面試時(shí)的必備良題啊),相信下圖已經(jīng)表達(dá)得非常清除了
            其次是winsocket與tcp/ip(其實(shí),不止TCP/IP協(xié)議族,這里只討論TCP/IP) 
            TCP/IP協(xié)議核心與應(yīng)用程序關(guān)系圖。

            最后是常用協(xié)議特性:
             關(guān)于定址
            Winsock中,通過(guò)SOCKADDR_IN結(jié)構(gòu)來(lái)描述IP地址和服務(wù)端口:
            struct sockaddr_in
            {
                  short                             sin_family;
                  u_short                         sin_port;
                  struct in_addr               sin_addr;
                  char                              sin_zero[8];
            };
            哦,我只關(guān)心IP協(xié)議,所以sin_family = AF_INET;
            關(guān)于端口要注意哦,0-1023為固定服務(wù)保留的(別打他們的注意了);1024-49151供普通用戶的普通用戶進(jìn)程使用;49152-65535是動(dòng)態(tài)和私有端口。
            幾個(gè)特殊地址:
              INADDR_ANY:允許服務(wù)器應(yīng)用監(jiān)聽(tīng)主機(jī)上每個(gè)網(wǎng)絡(luò)接口上的客戶機(jī)活動(dòng);
              INADDR_BROADCAST用于在一個(gè)IP網(wǎng)絡(luò)中發(fā)送廣播UDP數(shù)據(jù)報(bào)。
            字節(jié)排序:
            從主機(jī)字節(jié)順序---> 網(wǎng)絡(luò)字節(jié)順序
            返回四字節(jié),用于IP地址
            u_long htonl(u_long hostlong)
            int WSAHtonl(
                    SOCKET s,
                    u_long hostlong,
                    u_long FAR * lpnetlong
            );
            返回兩字節(jié),用于端口號(hào)
            u_short htons(u_short hostshort);
            int WSAHtons(
                  SOCKET s,
                  u_short hostshort,
                  u_short FAR * lpnetshort
            ); 
            對(duì)應(yīng)的反向函數(shù):
            u_long ntohl(u_long netong)
            int WSANtohl(
                    SOCKETs,
                    u_long netong,
                    u_long FAR * lphostlong
            );
            u_short htons(u_short netshort);
            int WSANtons(
                  SOCKET s,
                  u_short netshort,
                  u_short FAR * lphostshort
            ); 
            進(jìn)入winsocket
             下面開(kāi)始整理winsocket 的一些細(xì)節(jié):
             所有的winsocket應(yīng)用其實(shí)都是調(diào)用winsock dll 中的方法,所以通過(guò)WSAstartup加載是第一步。否則就會(huì)出錯(cuò):WSANOTINITIALISED(10093)。
            下面先來(lái)看看面向連接的協(xié)議:
            從服務(wù)器端來(lái)看:
            1.bind,將套接字和一個(gè)已知的地址進(jìn)行綁定。
             
            這樣就創(chuàng)建了一個(gè)流套接字,這個(gè)步驟最常見(jiàn)的錯(cuò)誤是WSAEADDRINUSE (10048) ,表示另外一個(gè)進(jìn)程已經(jīng)和本地IP和端口進(jìn)行了綁定,或者那個(gè)IP地址和端口號(hào)處于TIME_WAIT狀態(tài)。
            2.Listen,將套接字置于監(jiān)聽(tīng)狀態(tài)。
              
              int listen(
                    SOCKET s,
                   int backlog
                )
            backlog參數(shù)指定了正在等待連接的最大隊(duì)列長(zhǎng)度,如果實(shí)際訪問(wèn)的客戶端大于該最大長(zhǎng)度就會(huì)出錯(cuò):WSAECONNREFUSED (10061)。事實(shí)上該backlog本身也是由基層協(xié)議提供者決定的。在這個(gè)階段還有一種常見(jiàn)的錯(cuò)誤就是WSAEINVAL (10022),即沒(méi)有綁定就進(jìn)行監(jiān)聽(tīng)了。
            3.accept和WSAAccept
            SOCKET accept(
            SOCKET s,
            struct sockaddr FAR *addr,
            int FAR* addrlen,
            調(diào)用accept可為待決連接隊(duì)列中的第一個(gè)連接請(qǐng)求提供服務(wù)。(在服務(wù)器端接收連接前,所有的客戶端連接請(qǐng)求是放在一個(gè)“待決”隊(duì)列中的。)
            accept會(huì)返回一個(gè)新的套接字描述符,它對(duì)應(yīng)于已經(jīng)接受的那個(gè)客戶機(jī)連接。對(duì)于
            該客戶機(jī)后續(xù)的所有操作,都應(yīng)使用這個(gè)新套接字。至于原來(lái)那個(gè)監(jiān)聽(tīng)套接字,它仍然用于
            接受其他客戶機(jī)連接,而且仍處于監(jiān)聽(tīng)模式。
            SOCKET WSAAccept(
            SOCKET s,
            struct sockaddr FAR *addr,
            LPINT addrlen,
            LPCONDITIONPROC lpfncondition,
            DWORD dwCallBackData
            對(duì)于客戶端相對(duì)要簡(jiǎn)單得多,主要由以下幾步:
            1) 用socket或WSASocket創(chuàng)建一個(gè)套接字。
            2) 解析服務(wù)器名(以基層協(xié)議為準(zhǔn))。
            3) 用connect或WSAConnect初始化一個(gè)連接。
            在connect過(guò)程常發(fā)生的錯(cuò)誤有:WSAECONNREFUSED (10061)連接的計(jì)算機(jī)沒(méi)有監(jiān)聽(tīng)指定端口的進(jìn)程;WSAETIMEDOUT (10060)這種情況一般發(fā)生在試圖連接的計(jì)算機(jī)不能用時(shí)(亦可能因?yàn)榈街鳈C(jī)之間的路由上出現(xiàn)硬件故障或主機(jī)目前不在網(wǎng)上)。
            連接之后就是數(shù)據(jù)傳輸了,就是發(fā)送和接收了:
            int send(
                SOCKET s,
                const char FAR * buf,
                int len,
                int flags)
            返回發(fā)送的字節(jié)數(shù),如果出錯(cuò)常見(jiàn)的錯(cuò)誤是:WSAECONNABORTED (10053) 這一錯(cuò)誤一般發(fā)生在虛擬回路由于超時(shí)或協(xié)議有錯(cuò)而中斷的時(shí)候。遠(yuǎn)程主機(jī)上的應(yīng)用通過(guò)執(zhí)行強(qiáng)行關(guān)閉或意外中斷操作重新設(shè)置虛擬虛路時(shí),或遠(yuǎn)程主機(jī)重新啟動(dòng)時(shí),發(fā)生的則是WSAECONNRESET(10054)錯(cuò)誤。。最后一個(gè)常見(jiàn)錯(cuò)誤是WSAETIMEOUT(10060),它發(fā)生在連接由于網(wǎng)絡(luò)故障或遠(yuǎn)程連接系統(tǒng)異常死機(jī)而引起的連接中斷時(shí)。
            int recv(
                SOCKET s,
                const char FAR * buf,
                int len,
                int flags)
            無(wú)連接協(xié)議
                首先從接收端(類似于有連接方式中的服務(wù)端,但不是服務(wù)端)看,首先也是通過(guò)socket或WSAsocket創(chuàng)建套接字。再通過(guò)bind進(jìn)行綁定。下面跳過(guò)Listen和Accept步驟,直接等待接收就可以了。
            接收函數(shù):
            int recvfrom(
                SOCKET s,
                char FAR * buf,
                int len,
                int flags,
                struct SockAddr FAR *from,
                int FAR * fromlen
            )
            發(fā)送:建立SCOKET后調(diào)用sendto或WSASendTo
            int sendto(
                SOCKET s,
                char FAR * buf,
                int len,
                int flags,
                struct SockAddr FAR * to,
                int FAR * tolen
            )

            posted on 2008-03-18 11:16 隨意門(mén) 閱讀(605) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            青草国产精品久久久久久| 国产精品美女久久久久av爽| 思思久久99热只有频精品66| 久久精品免费全国观看国产| 久久精品中文騷妇女内射| 国产激情久久久久影院小草 | 影音先锋女人AV鲁色资源网久久| 99久久做夜夜爱天天做精品| 97久久久精品综合88久久| 99久久亚洲综合精品成人| 久久亚洲国产精品成人AV秋霞| 国产成人精品免费久久久久| 亚洲国产精品成人AV无码久久综合影院| 中文精品99久久国产 | 亚洲日本久久久午夜精品| 久久婷婷五月综合色高清| 久久国产乱子伦精品免费午夜| 久久婷婷成人综合色综合| 伊人久久大香线蕉成人| 国产精品午夜久久| 99久久中文字幕| 久久精品无码专区免费东京热| 久久精品夜色噜噜亚洲A∨| 久久精品国产一区| 天天爽天天狠久久久综合麻豆 | 囯产精品久久久久久久久蜜桃| 精品国产综合区久久久久久| 久久精品无码一区二区三区| 久久精品国产第一区二区三区| 午夜久久久久久禁播电影| 久久久久av无码免费网| 性做久久久久久久久浪潮| 伊人久久大香线蕉无码麻豆| 理论片午午伦夜理片久久 | 无码伊人66久久大杳蕉网站谷歌| 伊色综合久久之综合久久| 2020国产成人久久精品| 狠狠色综合网站久久久久久久高清| 性高朝久久久久久久久久| 久久综合亚洲鲁鲁五月天| 欧美日韩精品久久久免费观看|