• <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>
            隨筆 - 96  文章 - 255  trackbacks - 0
            <2010年6月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            E-mail:zbln426@163.com QQ:85132383 長期尋找對戰(zhàn)略游戲感興趣的合作伙伴。

            常用鏈接

            留言簿(21)

            隨筆分類

            隨筆檔案

            SDL相關(guān)網(wǎng)站

            我的個人網(wǎng)頁

            我的小游戲

            資源下載

            搜索

            •  

            積分與排名

            • 積分 - 493539
            • 排名 - 39

            最新評論

            閱讀排行榜

            評論排行榜

            作者:龍飛

                    這里的“通訊”加上了引號,是因為實際上所有的socket都有通訊的功能,只是在我們的例子中,之前那個socket只負(fù)責(zé)listen,而這個socket負(fù)責(zé)接受信息并echo回去。
             我們現(xiàn)看看這個函數(shù):
            bool TcpServer::isAccept()
            {
                unsigned 
            int clntAddrLen = sizeof(clntAddr);

                
            if ( (communicationSock = accept(listenSock, (sockaddr*)&clntAddr, &clntAddrLen)) < 0 ) {
                    
            return false;
                } 
            else {
                    std::cout 
            << "Client(IP: " << inet_ntoa(clntAddr.sin_addr) << ") connected.\n";
                    
            return true;
                }
            }

            用accept()創(chuàng)建新的socket

                    在我們的例子中,communicationSock實際上是用函數(shù)accept()創(chuàng)建的。
            int accept(int socket, struct sockaddr* clientAddress, unsigned int* addressLength);
            在Linux中的實現(xiàn)為:
            /* Await a connection on socket FD.
               When a connection arrives, open a new socket to communicate with it,
               set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
               peer and *ADDR_LEN to the address's actual length, and return the
               new socket's descriptor, or -1 for errors.

               This function is a cancellation point and therefore not marked with
               __THROW.  
            */
            extern int accept (int __fd, __SOCKADDR_ARG __addr,
                       socklen_t 
            *__restrict __addr_len);
            這個函數(shù)實際上起著構(gòu)造socket作用的僅僅只有第一個參數(shù)(另外還有一個不在這個函數(shù)內(nèi)表現(xiàn)出來的因素,后面會討論到),后面兩個指針都有副作用,在socket創(chuàng)建后,會將客戶端sockaddr的數(shù)據(jù)以及結(jié)構(gòu)體的大小傳回。
                    當(dāng)程序調(diào)用accept()的時候,程序有可能就停下來等accept()的結(jié)果。這就是我們前一小節(jié)說到的block(阻塞)。這如同我們調(diào)用std::cin的時候系統(tǒng)會等待輸入直到回車一樣。accept()是一個有可能引起block的函數(shù)。請注意我說的是“有可能”,這是因為accept()的block與否實際上決定與第一個參數(shù)socket的屬性。這個文件描述符如果是block的,accept()就block,否則就不block。默認(rèn)情況下,socket的屬性是“可讀可寫”,并且,是阻塞的。所以,我們不修改socket屬性的時候,accept()是阻塞的。

            accept()的另一面connect()

                    accept()只是在server端被動的等待,它所響應(yīng)的,是client端connect()函數(shù):
            int connect(int socket, struct sockaddr* foreignAddress, unsigned int addressLength);
            雖然我們這里不打算詳細(xì)說明這個client端的函數(shù),但是我們可以看出來,這個函數(shù)與之前我們介紹的bind()有幾分相似,特別在Linux的實現(xiàn)中:
            /* Open a connection on socket FD to peer at ADDR (which LEN bytes long).
               For connectionless socket types, just set the default address to send to
               and the only address from which to accept transmissions.
               Return 0 on success, -1 for errors.

               This function is a cancellation point and therefore not marked with
               __THROW.  
            */
            extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
            connect() 也使用了const的sockaddr,只不過是遠(yuǎn)程電腦上的而非bind()的本機。
                    accept()在server端表面上是通過listen socket創(chuàng)建了新的socket,實際上,這種行為是在接受對方客戶機程序中connect()函數(shù)的請求后發(fā)生的。綜合起看,被創(chuàng)建的新socket實際上包含了listen socket的信息以及客戶端connect()請求中所包含的信息——客戶端的sockaddr地址。

            新socket與sockaddr的關(guān)系

                    accept()創(chuàng)建的新socket(我們例子中的communicationSock,這里我們簡單用newSock來帶指)首先包含了listen socket的信息,所以,newSock具有本機sockaddr的信息;其次,因為它響應(yīng)于client端connect()函數(shù)的請求,所以,它還包含了clinet端sockaddr的信息。
                    我們說過,stream流形式的TCP協(xié)議實際上是建立起一個“可來可去”的通道。用于listen的通道,遠(yuǎn)程機的目標(biāo)地址是不確定的;但是newSock卻是有指定的本機地址和遠(yuǎn)程機地址,所以,這個socket,才是我們真正用于TCP“通訊”的socket。

            inet_ntoa()
            #include <arpa/inet.h>

            /* Convert Internet number in IN to ASCII representation.  The return value
               is a pointer to an internal array containing the string.  
            */
            extern char *inet_ntoa (struct in_addr __in) __THROW;
                    對于這個函數(shù),我們可以作為一種,將IP地址,由in_addr結(jié)構(gòu)轉(zhuǎn)換為可讀的ASCII形式的固定用法。

            posted on 2008-07-15 13:04 lf426 閱讀(4205) 評論(0)  編輯 收藏 引用 所屬分類: SDL入門教程Linux與C++socket 編程入門教程
            国产亚洲精品久久久久秋霞| 国产成人综合久久久久久| 欧美日韩久久中文字幕| 精品久久久中文字幕人妻| 久久99精品国产自在现线小黄鸭 | 精品乱码久久久久久夜夜嗨| 久久综合五月丁香久久激情| 色婷婷综合久久久久中文| 久久本道久久综合伊人| 午夜精品久久久久久中宇| 久久综合九色综合欧美就去吻| 精品久久久久久成人AV| 亚洲美日韩Av中文字幕无码久久久妻妇 | 久久99精品久久久久久久不卡| 久久国产精品偷99| avtt天堂网久久精品| 一本久久a久久精品综合香蕉| 色综合久久久久| 99久久精品日本一区二区免费| 久久这里的只有是精品23| 久久人人超碰精品CAOPOREN| .精品久久久麻豆国产精品| 亚洲AV无码久久精品狠狠爱浪潮| 久久久国产精华液| 99久久99久久精品国产片果冻| 国产午夜免费高清久久影院| 97精品国产97久久久久久免费| 欧美与黑人午夜性猛交久久久 | 97久久精品无码一区二区 | 欧美无乱码久久久免费午夜一区二区三区中文字幕| 亚洲精品无码久久久久| 99蜜桃臀久久久欧美精品网站 | 久久久久久精品免费看SSS| 无码国内精品久久人妻麻豆按摩| 亚洲国产精品人久久| 情人伊人久久综合亚洲| 久久精品成人免费网站| segui久久国产精品| 久久人人超碰精品CAOPOREN| 亚洲欧洲久久久精品| 人人狠狠综合久久88成人|