亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

IOS開發網絡篇―Socket編程詳解

2020-07-26 03:13:20
字體:
來源:轉載
供稿:網友

一、網絡各個協議:TCP/IP、SOCKET、HTTP等

網絡七層由下往上分別為物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層和應用層。

其中物理層、數據鏈路層和網絡層通常被稱作媒體層,是網絡工程師所研究的對象;

傳輸層、會話層、表示層和應用層則被稱作主機層,是用戶所面向和關心的內容。

http協議對應于應用層

tcp協議對應于傳輸層

ip協議對應于網絡層

三者本質上沒有可比性。  何況HTTP協議是基于TCP連接的。

TCP/IP是傳輸層協議,主要解決數據如何在網絡中傳輸;而HTTP是應用層協議,主要解決如何包裝數據。

我 們在傳輸數據時,可以只使用傳輸層(TCP/IP),但是那樣的話,由于沒有應用層,便無法識別數據內容,如果想要使傳輸的數據有意義,則必須使用應用層 協議,應用層協議很多,有HTTP、FTP、TELNET等等,也可以自己定義應用層協議。WEB使用HTTP作傳輸層協議,以封裝HTTP文本信息,然 后使用TCP/IP做傳輸層協議將它發送到網絡上。Socket是對TCP/IP協議的封裝,Socket本身并不是協議,而是一個調用接口(API),通過Socket,我們才能使用TCP/IP協議。

二、Http和Socket連接區別

相信不少初學手機聯網開發的朋友都想知道Http與Socket連接究竟有什么區別,希望通過自己的淺顯理解能對初學者有所幫助。

2.1、TCP連接

要想明白Socket連接,先要明白TCP連接。手機能夠使用聯網功能是因為手機底層實現了TCP/IP協議,可以使手機終端通過無線網絡建立TCP連接。TCP協議可以對上層網絡提供接口,使上層網絡數據的傳輸建立在“無差別”的網絡之上。

建立起一個TCP連接需要經過“三次握手”:

第一次握手:客戶端發送syn包(syn=j)到服務器,并進入SYN_SEND狀態,等待服務器確認;

第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;

第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。

手過程中傳送的包里不包含數據,三次握手完畢后,客戶端與服務器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP連接都將被一直保持下去。斷開連接時服務器和客戶端均可以主動發起斷開TCP連接的請求,斷開過程需要經過“四次握手”(過程就不細寫了,就是服務器和客戶端交互,最終確定斷開)

2.2、HTTP連接

HTTP協議即超文本傳送協議(HypertextTransfer Protocol ),是Web聯網的基礎,也是手機聯網常用的協議之一,HTTP協議是建立在TCP協議之上的一種應用。

HTTP連接最顯著的特點是客戶端發送的每次請求都需要服務器回送響應,在請求結束后,會主動釋放連接。從建立連接到關閉連接的過程稱為“一次連接”。

1)在HTTP 1.0中,客戶端的每次請求都要求建立一次單獨的連接,在處理完本次請求后,就自動釋放連接。

2)在HTTP 1.1中則可以在一次連接中處理多個請求,并且多個請求可以重疊進行,不需要等待一個請求結束后再發送下一個請求。

由于HTTP在每次請求結束后都會主動釋放連接,因此HTTP連接是一種“短連接”,要保持客戶端程序的在線狀態,需要不斷地向服務器發起連接請求。通常的做法是即時不需要獲得任何數據,客戶端也保持每隔一段固定的時間向服務器發送一次“保持連接”的請求,服務器在收到該請求后對客戶端進行回復,表明知道客戶端“在線”。若服務器長時間無法收到客戶端的請求,則認為客戶端“下線”,若客戶端長時間無法收到服務器的回復,則認為網絡已經斷開。

三、SOCKET原理

3.1、套接字(socket)概念

套接字(socket)是通信的基石,是支持TCP/IP協議的網絡通信的基本操作單元。它是網絡通信過程中端點的抽象表示,包含進行網絡通信必須的五種信息:連接使用的協議,本地主機的IP地址,本地進程的協議端口,遠地主機的IP地址,遠地進程的協議端口。

應用層通過傳輸層進行數據通信時,TCP會遇到同時為多個應用程序進程提供并發服務的問題。多個TCP連接或多個應用程序進程可能需要通過同一個

TCP協議端口傳輸數據。為了區別不同的應用程序進程和連接,許多計算機操作系統為應用程序與TCP/IP協議交互提供了套接字(Socket)接口。應用層可以和傳輸層通過Socket接口,區分來自不同應用程序進程或網絡連接的通信,實現數據傳輸的并發服務。

3.2 、建立socket連接

建立Socket連接至少需要一對套接字,其中一個運行于客戶端,稱為ClientSocket,另一個運行于服務器端,稱為ServerSocket。

套接字之間的連接過程分為三個步驟:服務器監聽,客戶端請求,連接確認。

服務器監聽:服務器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態,實時監控網絡狀態,等待客戶端的連接請求。

客戶端請求:指客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然后就向服務器端套接字提出連接請求。

連接確認:當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式建立連接。而服務器端套接字繼續處于監聽狀態,繼續接收其他客戶端套接字的連接請求。

3.3、SOCKET連接與TCP連接

創建Socket連接時,可以指定使用的傳輸層協議,Socket可以支持不同的傳輸層協議(TCP或UDP),當使用TCP協議進行連接時,該Socket連接就是一個TCP連接。

3.4、Socket連接與HTTP連接

由于通常情況下Socket連接就是TCP連接,因此Socket連接一旦建立,通信雙方即可開始相互發送數據內容,直到雙方連接斷開。但在實際網絡應用中,客戶端到服務器之間的通信往往需要穿越多個中間節點,例如路由器、網關、防火墻等,大部分防火墻默認會關閉長時間處于非活躍狀態的連接而導致Socket 連接斷連,因此需要通過輪詢告訴網絡,該連接處于活躍狀態。

而HTTP連接使用的是“請求―響應”的方式,不僅在請求時需要先建立連接,而且需要客戶端向服務器發出請求后,服務器端才能回復數據。很多情況下,需要服務器端主動向客戶端推送數據,保持客戶端與服務器數據的實時與同步。此時若雙方建立的是Socket連接,服務器就可以直接將數據傳送給

客戶端;若雙方建立的是HTTP連接,則服務器需要等到客戶端發送一次請求后才能將數據傳回給客戶端,因此,客戶端定時向服務器端發送連接請求,不僅可以保持在線,同時也是在“詢問”服務器是否有新的數據,如果有就將數據傳給客戶端。

這里我們使用Socket實現一個聊天室的功能,關于服務器這里的就不介紹了

一:再頭文件中第一輸入流和輸出流和一個消息數組

@interfaceViewController (){NSInputStream *_inputStream;//對應輸入流NSOutputStream *_outputStream;//對應輸出流}@property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputViewConstraint;@property (weak, nonatomic) IBOutlet UITableView *tableView;@property (nonatomic, strong) NSMutableArray *chatMsgs;//聊天消息數組@end懶加載這個消息數組-(NSMutableArray *)chatMsgs{if(!_chatMsgs) {_chatMsgs =[NSMutableArray array];}return_chatMsgs;}

二:實現輸入輸出流的監聽

-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{NSLog(@"%@",[NSThread currentThread]);//NSStreamEventOpenCompleted = 1UL << 0,//輸入輸出流打開完成//NSStreamEventHasBytesAvailable = 1UL << 1,//有字節可讀//NSStreamEventHasSpaceAvailable = 1UL << 2,//可以發放字節//NSStreamEventErrorOccurred = 1UL << 3,//連接出現錯誤//NSStreamEventEndEncountered = 1UL << 4//連接結束switch(eventCode) {caseNSStreamEventOpenCompleted:NSLog(@"輸入輸出流打開完成");break;caseNSStreamEventHasBytesAvailable:NSLog(@"有字節可讀");[self readData];break;caseNSStreamEventHasSpaceAvailable:NSLog(@"可以發送字節");break;caseNSStreamEventErrorOccurred:NSLog(@"連接出現錯誤");break;caseNSStreamEventEndEncountered:NSLog(@"連接結束");//關閉輸入輸出流[_inputStream close];[_outputStream close];//從主運行循環移除[_inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];[_outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];break;default:break;}}

三:鏈接服務器

1- (IBAction)connectToHost:(id)sender {//1.建立連接NSString *host =@"127.0.0.1";intport =12345;//定義C語言輸入輸出流CFReadStreamRef readStream;CFWriteStreamRef writeStream;CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);//把C語言的輸入輸出流轉化成OC對象_inputStream = (__bridge NSInputStream *)(readStream);_outputStream = (__bridge NSOutputStream *)(writeStream);//設置代理_inputStream.delegate=self;_outputStream.delegate=self;//把輸入輸入流添加到主運行循環//不添加主運行循環 代理有可能不工作[_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];[_outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];//打開輸入輸出流[_inputStream open];[_outputStream open];}

四:登陸

- (IBAction)loginBtnClick:(id)sender {//登錄//發送用戶名和密碼//在這里做的時候,只發用戶名,密碼就不用發送//如果要登錄,發送的數據格式為 "iam:zhangsan";//如果要發送聊天消息,數據格式為 "msg:did you have dinner";//登錄的指令11NSString *loginStr =@"iam:zhangsan";//把Str轉成NSDataNSData *data =[loginStr dataUsingEncoding:NSUTF8StringEncoding];[_outputStream write:data.bytes maxLength:data.length];}

五:讀取服務器數據

#pragmamark 讀了服務器返回的數據-(void)readData{//建立一個緩沖區 可以放1024個字節uint8_t buf[1024];//返回實際裝的字節數NSInteger len = [_inputStream read:buf maxLength:sizeof(buf)];//把字節數組轉化成字符串NSData *data =[NSData dataWithBytes:buf length:len];//從服務器接收到的數據NSString *recStr =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];NSLog(@"%@",recStr);[self reloadDataWithText:recStr];}

六:發送數據

-(BOOL)textFieldShouldReturn:(UITextField *)textField{NSString *text =textField.text;NSLog(@"%@",text);//聊天信息NSString *msgStr = [NSString stringWithFormat:@"msg:%@",text];//把Str轉成NSData10NSData *data =[msgStr dataUsingEncoding:NSUTF8StringEncoding];//刷新表格[self reloadDataWithText:msgStr];//發送數據[_outputStream write:data.bytes maxLength:data.length];//發送完數據,清空textFieldtextField.text =nil;returnYES;}

七:實現數據的顯示,并且每發送一次消息都會滾動到對應的位置

-(void)reloadDataWithText:(NSString *)text{[self.chatMsgs addObject:text];[self.tableView reloadData];//數據多,應該往上滾動NSIndexPath *lastPath = [NSIndexPath indexPathForRow:self.chatMsgs.count -1inSection:0];[self.tableView scrollToRowAtIndexPath:lastPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];}#pragmamark 表格的數據源-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{returnself.chatMsgs.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{staticNSString *ID =@"Cell";UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:ID];cell.textLabel.text =self.chatMsgs[indexPath.row];returncell;}-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{[self.view endEditing:YES];}

八:監聽鍵盤的改變

//監聽鍵盤[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kbFrmWillChange:) name:UIKeyboardWillChangeFrameNotificationobject:nil];}-(void)kbFrmWillChange:(NSNotification *)noti{NSLog(@"%@",noti.userInfo);//獲取窗口的高度CGFloat windowH =[UIScreen mainScreen].bounds.size.height;//鍵盤結束的FrmCGRect kbEndFrm =[noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];//獲取鍵盤結束的y值CGFloat kbEndY =kbEndFrm.origin.y;self.inputViewConstraint.constant = windowH -kbEndY;}

文/牽左手不離(簡書作者)
原文鏈接:http://www.jianshu.com/p/6b64d8ac62e3
著作權歸作者所有,轉載請聯系作者獲得授權,并標注“簡書作者”。

以上就是IOS開發網絡篇―Socket編程的資料整理,后續繼續補充相關資料,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国产自在精品国产浪潮| 欧美三级免费观看| 国产精品视频自在线| 久久的精品视频| 久久亚洲精品中文字幕冲田杏梨| 国产精品视频999| 国产成人精品久久二区二区91| 欧美日韩中文在线| 国产精品视频公开费视频| 欧美裸身视频免费观看| 欧美主播福利视频| 日韩欧美在线观看视频| 亚洲精品中文字幕有码专区| 日韩动漫免费观看电视剧高清| 久久伊人精品一区二区三区| 日韩av片电影专区| 亚洲黄色av网站| 欧美日韩亚洲激情| 在线色欧美三级视频| 欧美黄色免费网站| 午夜精品免费视频| 视频直播国产精品| 国产精品视频免费观看www| 欧美精品一区二区免费| 91欧美日韩一区| 久久久久北条麻妃免费看| 精品成人国产在线观看男人呻吟| 热re99久久精品国产66热| 久久激情视频免费观看| 国产精品国产自产拍高清av水多| 国产精品日日摸夜夜添夜夜av| 国产中文欧美精品| 亚洲黄色成人网| 国产精品精品久久久久久| 欧美在线免费看| 欧美性理论片在线观看片免费| 国产在线视频一区| 色诱女教师一区二区三区| 日韩中文有码在线视频| 欧美一级淫片丝袜脚交| 国产欧美精品久久久| 国产精品91免费在线| 国产精品久久91| 91沈先生作品| 神马国产精品影院av| 亚洲精品久久久一区二区三区| 美女福利视频一区| 久久久欧美一区二区| 国产97免费视| 色噜噜久久综合伊人一本| 欧美野外猛男的大粗鳮| 91九色单男在线观看| 色爱av美腿丝袜综合粉嫩av| 久久免费视频网站| 欧美午夜精品在线| 欧美日韩成人在线观看| 91中文在线观看| 国产日韩亚洲欧美| 一本一本久久a久久精品综合小说| 日韩在线观看高清| …久久精品99久久香蕉国产| 亚洲第一区第一页| 日韩女在线观看| 中文国产亚洲喷潮| 日本精品视频在线观看| 欧美成人精品一区| 亚洲成**性毛茸茸| 国产欧美日韩亚洲精品| 在线观看91久久久久久| 国产精品69精品一区二区三区| 国产亚洲精品一区二555| 精品少妇一区二区30p| 海角国产乱辈乱精品视频| 国产热re99久久6国产精品| 最近2019年手机中文字幕| 久久777国产线看观看精品| 国产精品草莓在线免费观看| 欧美最近摘花xxxx摘花| 中文字幕亚洲欧美一区二区三区| 亚洲欧美中文字幕| 精品久久久久久久久久久久| 欧美一区二区影院| 另类美女黄大片| 亚洲香蕉av在线一区二区三区| 粉嫩老牛aⅴ一区二区三区| 91九色视频在线| 国外成人在线直播| 在线成人中文字幕| 亚洲jizzjizz日本少妇| 亚洲国产古装精品网站| 久久精品国产欧美亚洲人人爽| 日韩专区中文字幕| 日韩精品高清在线观看| 久久久久久久久国产精品| 亚洲激情中文字幕| 韩国精品美女www爽爽爽视频| 亚洲一区免费网站| 亚洲欧美另类中文字幕| 久久久久久成人| 日韩国产一区三区| 久久影院资源站| 中文字幕一精品亚洲无线一区| 中文字幕国产精品| 亚洲精品成人久久| 国产精品黄色影片导航在线观看| 伊人成人开心激情综合网| 69av在线播放| 成人午夜在线视频一区| 日韩精品在线视频美女| 亚洲精品久久久久久久久久久久| 欧美怡春院一区二区三区| 日韩乱码在线视频| 91av在线视频观看| 亚洲欧美日韩精品久久亚洲区| 在线a欧美视频| 欧美另类老女人| 91久久精品国产91久久| 中文字幕精品—区二区| 国产一区二区色| 国产美女主播一区| 亚洲成年人在线播放| 中文字幕日韩欧美精品在线观看| 欧美伊久线香蕉线新在线| 久热在线中文字幕色999舞| 久久久www成人免费精品张筱雨| 色悠久久久久综合先锋影音下载| 欧美性生交xxxxx久久久| 欧美在线观看一区二区三区| 久久久亚洲福利精品午夜| 91久久精品美女| 国产精品免费视频xxxx| 国产一区二区三区在线看| 国产精品久久电影观看| 国产精品久久久久久婷婷天堂| 国产精品99久久久久久白浆小说| 欧美最顶级的aⅴ艳星| 疯狂蹂躏欧美一区二区精品| 不卡毛片在线看| 国产手机视频精品| 亚洲精品综合久久中文字幕| 亚洲视频在线观看网站| 在线观看日韩欧美| 69**夜色精品国产69乱| 日韩av在线影院| 国产精品美女主播在线观看纯欲| 亚洲日本中文字幕| 日韩中文字幕网址| 97国产精品视频人人做人人爱| 国产精品男人的天堂| 亚洲成人久久久| 国产美女精品免费电影| 色综合91久久精品中文字幕| 亚洲国产第一页| 中文字幕精品影院| 日本久久久久久久久| 欧美午夜精品伦理| 中文字幕亚洲在线| 欧美性高潮床叫视频| 2023亚洲男人天堂| 日本中文字幕久久看| 97在线视频精品| 欧美精品一区在线播放| 国产精品白丝av嫩草影院| 国产专区欧美专区|