iOS 網(wǎng)絡(luò)編程Socket

在網(wǎng)絡(luò)中,兩個程序之間是通過一個雙向的通信連接來實現(xiàn)數(shù)據(jù)交換的册养。這個連接的一端為Socket,又稱套接字揣云,包含了終端的IP地址捕儒、端口冰啃、傳輸協(xié)議等信息邓夕。

Socket是對TCP/IP的封裝,但它并不是一個協(xié)議阎毅,只是給程序員提供一個發(fā)送消息的接口焚刚,程序員使用這個接口提供的方法來發(fā)送和接收消息
網(wǎng)絡(luò)通信其實就是Socket之間的通信扇调,數(shù)據(jù)在兩個Socket之間通過IO傳輸矿咕。

要想實現(xiàn)Socket的通信,大致經(jīng)歷3個步驟,分別是創(chuàng)建一個Socket并建立連接碳柱、發(fā)送和接收信息捡絮、斷開連接、

一莲镣、創(chuàng)建Socket福稳,建立連接

創(chuàng)建一個Socket對象,通過socket()函數(shù)來實現(xiàn)

函數(shù)格式:
int socket(int domain,int type,int protocol);
domain: 協(xié)議域或者協(xié)議族,它決定了Socket的地址類型瑞侮,
通信中必須采用對應(yīng)的地址

type:指定Socket類型的圆,常用類型有
SOCK_STREAM、SOCK_DGRAM半火、SOCK_RAW越妈、SOCK_PACKET等

protocol:指定協(xié)議,常用協(xié)議有
IPPROTO_TCP钮糖、IPPROTO_UDP梅掠、IPPROTO_SCTP、IPPROTO_TIPC店归,
分別對應(yīng)TCP瓤檐、UDP、STCP娱节、TIPC傳輸協(xié)議挠蛉。

二、發(fā)送和接收信息

當(dāng)連接建立之后肄满,就可以發(fā)送和接收信息了谴古。發(fā)送信息通過send()函數(shù)來實現(xiàn)

ssize_t send(int,const void *,size_t,int)__DARWIN_ALIAS_C(send);
參數(shù)一:客戶端的Socket  

參數(shù)二:發(fā)送內(nèi)容的地址 

參數(shù)三:發(fā)送內(nèi)容的長度 

參數(shù)四:發(fā)送內(nèi)容的標(biāo)志,一般為0稠歉,
如發(fā)送成功掰担,返回信息內(nèi)容的字節(jié)數(shù)

客戶端將信息發(fā)送給服務(wù)器后,服務(wù)器會接收這個信息怒炸,通過recv()函數(shù)實現(xiàn)

ssize_t send(int,void
*,size_t,int)__DARWIN_ALIAS_C(recv);
參數(shù)一:客戶端的Socket  

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

參數(shù)三:接收內(nèi)容的長度 

參數(shù)四:接收的標(biāo)志带饱,如果為0表示阻塞式,
即會一直等待服務(wù)器返回數(shù)據(jù)

三阅羹、斷開連接

給服務(wù)器發(fā)送完信息勺疼,服務(wù)器回復(fù)信息后,需要斷開連接捏鱼,通過close()函數(shù)實現(xiàn)

int close(int);

四执庐、實戰(zhàn)-Socket聊天

Socket提供了發(fā)送和接收信息的接口,通過該接口實現(xiàn)了客戶端與服務(wù)器端的通信

創(chuàng)建工程导梆,設(shè)計界面

新建Single View Application應(yīng)用轨淌。 進入storyboard迂烁,拖拽1個label、2個button递鹉、3個Text Filed盟步。
建立效果大致如下:

storyboard.png

控件對象的關(guān)聯(lián)

/** 主機名 */
@property (weak, nonatomic) IBOutlet UITextField *hostText;
/** 端口號 */
@property (weak, nonatomic) IBOutlet UITextField *portText;
/** 發(fā)送的消息 */
@property (weak, nonatomic) IBOutlet UITextField *msgText;
/** 回復(fù)的消息 */
@property (weak, nonatomic) IBOutlet UILabel *recvLabel;

/** Socket */
@property(nonatomic, assign) int clientSocket;

實現(xiàn)Socket聊天

  • 導(dǎo)入 :
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
  • 自定義方法,通過傳入一個IP地址和端口號連接到服務(wù)器 :
/** 連接到服務(wù)器 */
- (BOOL)connectHost:(NSString *)host port:(int)port{
    //創(chuàng)建Socket對象
    self.clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    
    //建立連接
    struct sockaddr_in serverAddress;
    serverAddress.sin_family = AF_INET;//協(xié)議族
    
    //IP躏结、查找機器
    serverAddress.sin_addr.s_addr = inet_addr(host.UTF8String);
    serverAddress.sin_port = htons(port);//端口址芯、查找程序
    return (connect(self.clientSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress))==0);
    
}
  • 自定義方法,用于客戶端向服務(wù)器端發(fā)送一條信息
    服務(wù)器端向客戶端回復(fù)一條信息:
/** 發(fā)送和接收 */
- (NSString *)sendAndRecv:(NSString *)message{
    //發(fā)送信息
    size_t sendMsg = send(self.clientSocket, message.UTF8String, strlen(message.UTF8String), 0);
    
    //接收信息
    uint8_t buffer[1024];//定義一個數(shù)組
    ssize_t recvMsg = recv(self.clientSocket, buffer, sizeof(buffer), 0);
    
    //獲取服務(wù)器返回的二進制數(shù)據(jù)
    NSData *data = [NSData dataWithBytes:buffer length:recvMsg];
    
    //轉(zhuǎn)化為字符串
    NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    return str;
}
  • 自定義一個斷開連接的方法窜觉,用于中斷之前的連接
/** 斷開連接 */
- (void)disconnection{
    close(self.clientSocket);
}
  • 單擊'連接按鈕'谷炸,提示信息;單擊'發(fā)送按鈕'禀挫,接收到的信息顯示在label上
/** 單擊'連接按鈕'后事件 */
- (IBAction)clickConnectBtn {
    BOOL result = [self connectHost:self.hostText.text port:self.portText.text.intValue];
    
    self.recvLabel.text = result?@"成功":@"失敗";
}

/** 單擊'發(fā)送按鈕'后事件 */
- (IBAction)clickSendBtn {
    self.recvLabel.text = [self sendAndRecv:self.msgText.text];
}

運行程序

  • Run程序成功后旬陡,填入對應(yīng)的主機名和端口號[這里以12345為例],打開終端,輸入nc -lk 12345语婴,單擊模擬器上的連接按鈕描孟,底部標(biāo)簽提示成功后,在文本中輸入發(fā)送信息[例Hello]砰左,點擊發(fā)送按鈕匿醒,此時終端監(jiān)測到了發(fā)送來信息"Hello"。

  • 在終端中輸入"Hi"缠导,return之后廉羔,模擬器label提示"Hi"。這樣就成功的實現(xiàn)了Socket聊天僻造。

  • 效果圖

連接成功.png
發(fā)送成功.png
返回信息.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末憋他,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子髓削,更是在濱河造成了極大的恐慌竹挡,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件立膛,死亡現(xiàn)場離奇詭異揪罕,居然都是意外死亡,警方通過查閱死者的電腦和手機宝泵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門好啰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鲁猩,你說我怎么就攤上這事坎怪。” “怎么了廓握?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵搅窿,是天一觀的道長。 經(jīng)常有香客問我隙券,道長男应,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任娱仔,我火速辦了婚禮沐飘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘牲迫。我一直安慰自己耐朴,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布盹憎。 她就那樣靜靜地躺著筛峭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪陪每。 梳的紋絲不亂的頭發(fā)上影晓,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天,我揣著相機與錄音檩禾,去河邊找鬼挂签。 笑死,一個胖子當(dāng)著我的面吹牛盼产,可吹牛的內(nèi)容都是我干的饵婆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼戏售,長吁一口氣:“原來是場噩夢啊……” “哼啦辐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蜈项,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤芹关,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后紧卒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侥衬,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年跑芳,在試婚紗的時候發(fā)現(xiàn)自己被綠了轴总。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡博个,死狀恐怖怀樟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盆佣,我是刑警寧澤往堡,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布械荷,位于F島的核電站,受9級特大地震影響虑灰,放射性物質(zhì)發(fā)生泄漏吨瞎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一穆咐、第九天 我趴在偏房一處隱蔽的房頂上張望颤诀。 院中可真熱鬧,春花似錦对湃、人聲如沸崖叫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽心傀。三九已至,卻和暖如春斤儿,著一層夾襖步出監(jiān)牢的瞬間剧包,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工往果, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留疆液,地道東北人。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓陕贮,卻偏偏與公主長得像堕油,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子肮之,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355

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