iOS開(kāi)發(fā)輕松學(xué)習(xí)Socket

Socket是什么?

要了解什么是 Socket,首先需要了解 TCP/IP、UDP!?

TCP/IP(Transmission Control Protocol/Internet Protocol)即傳輸控制協(xié)議/網(wǎng)間協(xié)議脚作,是一個(gè)工業(yè)標(biāo)準(zhǔn)的協(xié)議集晋南,它是為廣域網(wǎng)(WANs)設(shè)計(jì)的贞铣。

UDP(User Data Protocol幅骄,用戶數(shù)據(jù)報(bào)協(xié)議)是與TCP相對(duì)應(yīng)的協(xié)議展哭。它是屬于TCP/IP協(xié)議族中的一種。

TCP/IP協(xié)議族包括運(yùn)輸層聪铺、網(wǎng)絡(luò)層化焕、鏈路層。現(xiàn)在你知道TCP/IP與UDP的關(guān)系了吧铃剔。


如果大家對(duì)于 七層協(xié)議模型 不是非常了解的話,你可以,沉下心來(lái)看看下面這張圖:

那么TCP/IP、UDP和socket又有什么關(guān)系呢???

Socket是應(yīng)用層與TCP/IP協(xié)議族通信的中間軟件抽象層查刻,它是一組接口键兜。在設(shè)計(jì)模式中,Socket其實(shí)就是一個(gè)門(mén)面模式穗泵,它把復(fù)雜的TCP/IP協(xié)議族隱藏在Socket接口后面普气,對(duì)用戶來(lái)說(shuō),一組簡(jiǎn)單的接口就是全部佃延,讓Socket去組織數(shù)據(jù)现诀,以符合指定的協(xié)議。

Socket怎么用

這里其實(shí)還有很多網(wǎng)絡(luò)相關(guān)的知識(shí)需要科普,但是篇幅有限,如果靚仔靚女的你對(duì)于這一塊有點(diǎn)陌生,你可以買(mǎi)一些網(wǎng)絡(luò)相關(guān)的書(shū)籍


《TCP/IP詳解 卷1:協(xié)議》

《圖解HTTP》

《Unix網(wǎng)絡(luò)編程》

HTTPS權(quán)威指南

Socket 作為一套接口,那么是怎么用的呢? 下面一圖勝前言:?

Socket 傳輸?shù)奶攸c(diǎn):


1: 傳輸數(shù)據(jù)為字節(jié)級(jí)履肃,傳輸數(shù)據(jù)可自定義仔沿,數(shù)據(jù)量小(對(duì)于手機(jī)應(yīng)用講:費(fèi)用低)

2: 傳輸數(shù)據(jù)時(shí)間短尺棋,性能高

3: 適合于客戶端和服務(wù)器端之間信息實(shí)時(shí)交互

4: 可以加密,數(shù)據(jù)安全性強(qiáng)


正因?yàn)檫@些優(yōu)勢(shì),常被用來(lái)做即時(shí)通訊重要媒介

上圖就是通過(guò) socket 在客戶端和終端做的來(lái)回通訊

socket使用代碼實(shí)現(xiàn):

1: 創(chuàng)建socket

int socketID = socket(AF_INET, SOCK_STREAM, 0);self.clinenId= socketID;if (socketID == -1) {? ? NSLog(@"創(chuàng)建socket 失敗");? ? return;}

(滑動(dòng)顯示更多)

domain:協(xié)議域封锉,又稱協(xié)議族(family)。常用的協(xié)議族有AF_INET膘螟、AF_INET6成福、AF_LOCAL(或稱AF_UNIX,Unix域Socket)荆残、AF_ROUTE等奴艾。協(xié)議族決定了socket的地址類(lèi)型,在通信中必須采用對(duì)應(yīng)的地址内斯,如AF_INET決定了要用ipv4地址(32位的)與端口號(hào)(16位的)的組合蕴潦、AF_UNIX決定了要用一個(gè)絕對(duì)路徑名作為地址。

type:指定Socket類(lèi)型嘿期。常用的socket類(lèi)型有SOCK_STREAM品擎、SOCK_DGRAM、SOCK_RAW备徐、SOCK_PACKET萄传、SOCK_SEQPACKET等。流式Socket(SOCK_STREAM)是一種面向連接的Socket,針對(duì)于面向連接的TCP服務(wù)應(yīng)用秀菱。數(shù)據(jù)報(bào)式Socket(SOCK_DGRAM)是一種無(wú)連接的Socket振诬,對(duì)應(yīng)于無(wú)連接的UDP服務(wù)應(yīng)用。

protocol:指定協(xié)議衍菱。常用協(xié)議有IPPROTO_TCP赶么、IPPROTO_UDP、IPPROTO_STCP脊串、IPPROTO_TIPC等辫呻,分別對(duì)應(yīng)TCP傳輸協(xié)議、UDP傳輸協(xié)議琼锋、STCP傳輸協(xié)議放闺、TIPC傳輸協(xié)議。

注意:1.type和protocol不可以隨意組合缕坎,如SOCK_STREAM不可以跟IPPROTO_UDP組合怖侦。當(dāng)?shù)谌齻€(gè)參數(shù)為0時(shí),會(huì)自動(dòng)選擇第二個(gè)參數(shù)類(lèi)型對(duì)應(yīng)的默認(rèn)協(xié)議谜叹。

返回值:如果調(diào)用成功就返回新創(chuàng)建的套接字的描述符匾寝,如果失敗就返回INVALID_SOCKET(Linux下失敗返回-1)

2: 建立連接

int result = connect(socketID, (const struct sockaddr *)&socketAddr, sizeof(socketAddr));if (result != 0) {? ? NSLog(@"鏈接失敗");? ? return;}NSLog(@"鏈接成功");

(滑動(dòng)顯示更多)

參數(shù)一:套接字描述符

參數(shù)二:指向數(shù)據(jù)結(jié)構(gòu)sockaddr的指針,其中包括目的端口和IP地址

參數(shù)三:參數(shù)二sockaddr的長(zhǎng)度荷腊,可以通過(guò)sizeof(struct sockaddr)獲得

返回值: 成功則返回0艳悔,失敗返回非0,錯(cuò)誤碼GetLastError()停局。

struct sockaddr_in socketAddr;socketAddr.sin_family = AF_INET;socketAddr.sin_port? = SocketPort;struct in_addr socketIn_addr;socketIn_addr.s_addr? = SocketIP;socketAddr.sin_addr???=?socketIn_addr;

(滑動(dòng)顯示更多)

__uint8_t sin_len;假如沒(méi)有這個(gè)成員很钓,其所占的一個(gè)字節(jié)被并入到sin_family成員中

sa_family_t sin_family;??一般來(lái)說(shuō)AF_INET(地址族)PF_INET(協(xié)議族)

in_port_t sin_port;?// 端口

struct in_addr sin_addr;//?ip

char sin_zero[8];沒(méi)有實(shí)際意義,只是為了 跟SOCKADDR結(jié)構(gòu)在內(nèi)存中對(duì)齊

3: 發(fā)送消息

if (self.sendMsgContent_tf.text.length == 0) {? ? return;}const char *msg = self.sendMsgContent_tf.text.UTF8String;ssize_t sendLen = send(self.clinenId, msg, strlen(msg), 0);NSLog(@"發(fā)送 %ld 字節(jié)",sendLen);[self showMsg:self.sendMsgContent_tf.text msgType:0];self.sendMsgContent_tf.text?=?@"";

(滑動(dòng)顯示更多)

s:一個(gè)用于標(biāo)識(shí)已連接套接口的描述字。

buf:包含待發(fā)送數(shù)據(jù)的緩沖區(qū)董栽。

len:緩沖區(qū)中數(shù)據(jù)的長(zhǎng)度码倦。

flags:調(diào)用執(zhí)行方式。

返回值: 如果成功锭碳,則返回發(fā)送的字節(jié)數(shù)袁稽,失敗則返回SOCKET_ERROR.一個(gè)中文對(duì)應(yīng) 3 個(gè)字節(jié)!UTF8?編碼擒抛!

4: 接受消息

while (1) {? ? uint8_t buffer[1024];? ? ssize_t recvLen = recv(self.clinenId, buffer, sizeof(buffer), 0);? ? if (recvLen == 0) {? ? ? ? NSLog(@"接收到了0個(gè)字節(jié)");? ? ? ? continue;? ? }? ? // buffer -> data -> string? ? NSData *data = [NSData dataWithBytes:buffer length:recvLen];? ? NSString *str= [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];? ? NSLog(@"%@---%@",[NSThread currentThread],str);? ? dispatch_async(dispatch_get_main_queue(), ^{? ? ? ? [self showMsg:str msgType:1];? ? ? ? self.sendMsgContent_tf.text = @"";? ? });}

(滑動(dòng)顯示更多)

參數(shù)一: 客戶端socket

參數(shù)二: 接收內(nèi)容緩沖區(qū)地址

參數(shù)三: 接收內(nèi)容緩存區(qū)長(zhǎng)度

參數(shù)四: 接收方式推汽,0表示阻塞,必須等待服務(wù)器返回?cái)?shù)據(jù)

返回值:如果成功歧沪,則返回讀入的字節(jié)數(shù)歹撒,失敗則返回SOCKET_ERROR

Socket 總結(jié)

Socket 的使用還是非常簡(jiǎn)單的! 對(duì)于iOS開(kāi)發(fā)有點(diǎn)吃力的原因是在于:


都是C函數(shù)

函數(shù)參數(shù)多并且陌生

網(wǎng)絡(luò)這一塊知識(shí)的盲區(qū)


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诊胞,隨后出現(xiàn)的幾起案子暖夭,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迈着,死亡現(xiàn)場(chǎng)離奇詭異竭望,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)裕菠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)咬清,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人奴潘,你說(shuō)我怎么就攤上這事旧烧。” “怎么了萤彩?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵粪滤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我雀扶,道長(zhǎng),這世上最難降的妖魔是什么肆汹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任愚墓,我火速辦了婚禮,結(jié)果婚禮上昂勉,老公的妹妹穿的比我還像新娘浪册。我一直安慰自己,他們只是感情好岗照,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布村象。 她就那樣靜靜地躺著,像睡著了一般攒至。 火紅的嫁衣襯著肌膚如雪厚者。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天迫吐,我揣著相機(jī)與錄音库菲,去河邊找鬼。 笑死志膀,一個(gè)胖子當(dāng)著我的面吹牛熙宇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播溉浙,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼烫止,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了戳稽?” 一聲冷哼從身側(cè)響起馆蠕,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后荆几,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體吓妆,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年吨铸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了行拢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诞吱,死狀恐怖舟奠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情房维,我是刑警寧澤沼瘫,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站咙俩,受9級(jí)特大地震影響耿戚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜阿趁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一膜蛔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脖阵,春花似錦皂股、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至悍募,卻和暖如春蘑辑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搜立。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工以躯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人啄踊。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓忧设,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親颠通。 傳聞我的和親對(duì)象是個(gè)殘疾皇子址晕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容