Socket 網路編程,socket網路編程

來源:互聯網
上載者:User

Socket 網路編程,socket網路編程
1.TCP/IP、UDP

TCP/IP(Transmission Control Protocol/Internet Protocol)即傳輸控制通訊協定/網間協議,是一個工業標準的協議集,它是為廣域網路(WANs)設計的。
UDP(User Data Protocol,使用者資料包通訊協定)是與TCP相對應的協議。它是屬於TCP/IP協議族中的一種。
下面這張圖,表明了這些協議的關係,TCP/IP協議族包括運輸層、網路層、鏈路層:

2.Socket

在圖1中,我們沒有看到Socket的影子,那麼它到底在哪裡呢?還是用圖來說話,一目瞭然。

Socket是應用程式層與TCP/IP協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對使用者來說,一組簡單的介面就是全部,讓Socket去組織資料,以符合指定的協議。

3.使用socket

前人已經給我們做了好多的事了,網路間的通訊也就簡單了許多,但畢竟還是有挺多工作要做的。以前聽到Socket編程,覺得它是比較高深的編程知識,但是只要弄清Socket編程的工作原理,神秘的面紗也就揭開了。

一個生活中的情境。你要打電話給一個朋友,先撥號,朋友聽到電話鈴聲後提起電話,這時你和你的朋友就建立起了串連,就可以講話了。等交流結束,掛斷電話結束此次交談。生活中的情境就解釋了這工作原理,也許TCP/IP協議族就是誕生於生活中,這也不一定。

4.程式碼範例
    #import "ViewController.h"    #import <sys/socket.h>    #import <netinet/in.h>    #import <arpa/inet.h>    @interface ViewController ()    // 用戶端 socket    @property (nonatomic, assign) int clientSocket;    @property (nonatomic, weak) IBOutlet UIWebView *myWebView;    @end    @implementation ViewController    /**     ======= 要求標頭 =======     1> 請求行        GET / HTTP/1.1        GET        表示從伺服器"拿"資料        /          訪問伺服器的根目錄        HTTP/1.1   HTTP的協議以及版本     2> 要求標頭        Host:              要訪問的主機        User-Agent:        使用者代理程式,告訴伺服器用戶端的類型        Accept:            告訴伺服器用戶端支援的資料格式        Accept-Language:   告訴伺服器用戶端支援的語言        Accept-Encoding:   告訴伺服器用戶端支援的解壓縮類型     HTTP請求本身的格式,是字串格式的,最末一行,以 \n\n 結束,表示所有請求的內容發送完畢,伺服器可以處理!     提示:key 值是 HTTP 協議定義的,不能隨意更改!    ==========響應 ===========     1> 狀態行        HTTP/1.1 200 OK     HTTP/1.1   HTTP的協議以及版本        200     狀態代碼(404)        2XX     成功        4XX     用戶端錯誤        5XX     伺服器錯誤     2> 回應標頭,伺服器告訴用戶端的一些資訊     提示:響應的資訊,通常在開發“下載”功能時,才會使用,平時用不著     Date:      響應日期     Server:    伺服器的資訊     // 檔案長度     Content-Length: 24     3> 資料實體,從伺服器返回的位元據!     println("hello world!");     */    - (void)viewDidLoad    {        [super viewDidLoad];        // http 連接埠是 80        if ([self connectToHost:@"61.135.169.125" port:80])        {            NSLog(@"串連成功");        }        // 發送訊息給 網頁伺服器        // 建立請求字串        NSString *request = @"GET / HTTP/1.1\n"        "Host: www.baidu.com\n"        "User-Agent: iPhone AppleWebKit\n\n";        // 對結果的處理        NSString *result = [self sendAndRecv:request];        // 找 \r\n 的出現的位置        NSRange range = [result rangeOfString:@"\r\n\r\n"];        // 判斷是否找到        if (range.location == NSNotFound)        {            NSLog(@"html 錯誤");            return;        }        NSString *html = [result substringFromIndex:range.location];        [self.myWebView loadHTMLString:html baseURL:[NSURL URLWithString:@"http://www.baidu.com"]];    }    - (BOOL)connectToHost:(NSString *)host port:(int)port    {        // 1. socket        /**         參數         domain:    協議域,AF_INET         type:      Socket 類型,SOCK_STREAM(流 TCP)/SOCK_DGRAM(報文,提示:                    在有些公司的程式員給伺服器發送資料,會說:發送報文)         protocol:  IPPROTO_TCP,提示:如果輸入0,會根據第二個參數,自動選擇協議         傳回值         socket     如果>0,就是正確的         */        self.clientSocket = socket(AF_INET, SOCK_STREAM, 0);        // 2. 串連到另外一台電腦        /**         參數         1> 用戶端socket         2> 指向資料結構sockaddr的指標,其中包括目的連接埠和IP地址            C 語言中沒有對象,實現都是通過結構體來實現的         3> 結構體資料長度         傳回值            0 成功/其他 錯誤代號,很多C語言的程式都會如此設計,原因:成功只有一個,失敗會有很多種!            C 語言中,通常是非零即真         */        struct sockaddr_in serverAddress;        // 1> 地址 inet_addr 可以將 ip 地址轉換成整數        // 提示:在網路上的使用的很多資料,需要做位元組翻轉        serverAddress.sin_addr.s_addr = inet_addr(host.UTF8String);        // 2> 連接埠 htons 可以將連接埠轉換成整數        // 連接埠號碼同樣要做位元組翻轉        serverAddress.sin_port = htons(port);        // 3> 協議        serverAddress.sin_family = AF_INET;        // 在 C 語言中,通常傳遞結構體的指標同時,會傳遞結構體的尺寸        int result = connect(self.clientSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress));        return (result == 0);    }    /**     *  發送&接收訊息     */    - (NSString *)sendAndRecv:(NSString *)msg {        // 3. 發送資料給伺服器        /**         參數         1> 用戶端socket         2> 發送內容地址         3> 發送內容長度         4> 發送方式標誌,一般為0         傳回值         如果成功,則返回傳送的位元組數,失敗則返回SOCKET_ERROR         提示:在很多C語言架構中,會將基礎資料型別 (Elementary Data Type)進行封裝,使用的時候,便於後續架構的調整         */        // 在 UTF8 編碼中,一個中文對應 3 個位元組        ssize_t sendLen = send(self.clientSocket, msg.UTF8String, strlen(msg.UTF8String), 0);        // 4. 從伺服器接收資料        uint8_t buffer[1024];        // 1> 定義一個可變的位元據,方便拼勁        NSMutableData *dataM = [NSMutableData data];        // 伺服器返回的斷行符號計數        int count = 0;        while (count == 0)        {            // 2> 接收資料            ssize_t recvLen = recv(self.clientSocket, buffer, sizeof(buffer), 0);            [dataM appendBytes:buffer length:recvLen];            // 通過跟蹤,\r\n\r\n 需要繼續等待,\r\n 表示傳輸結束            // 取末尾一個位元組            uint8_t lastByte = buffer[recvLen - 1];            // 取倒數第三個位元組            uint8_t preLastByte = buffer[recvLen - 3];            if (lastByte == '\n' && preLastByte != '\n') {                count++;            }        }        return [[NSString alloc] initWithData:dataM encoding:NSUTF8StringEncoding];    }    /**     *  中斷連線     */    - (void)disconnect {        // 5. 關閉串連        close(self.clientSocket);    }@end
5. 延伸閱讀

1.Linux socket 編程:
http://www.ibm.com/developerworks/cn/education/linux/l-sock/l-sock.html
2. 網路編程學習筆記一:Socket編程:
http://blog.csdn.net/gneveek/article/details/8699198

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.