计算机网络
2016-01-04 20:25
274 查看
计算机网络
======================对于程序员来讲,对计算机网络的了解是必要的。特别是基于IP和TCP/IP的网络以及Internet。此篇文章将向各位介绍关于计算机网络的相关基本知识
网络的定义
网络是用线缆连接,数据转换为通过线缆移动的电磁波。对于无线网络则是通过红外光和微波传输数据。
网络中的节点(node)
当你将你的计算机连接到计算机网络中,我们就将此计算机称为节点。虽然大多数节点都是计算机,但是像打印机、路由器、网桥、网关等终端也是节点,只要它们连接到计算机网络中。
我们将每个连入到计算机网络的设备称作为节点,对于每个节点来讲,计算机网络都会分配唯一的地址,这个地址是用于标识节点的一连串字节。事实上,我们两台连入计算机网络中的设备,要想通信,必须要知道对方的
节点地址。
对于
节点地址,事实上是一组数组。例如
192.168.1.1,这组数字就像人的身份证号码一样,可以唯一标志一个节点。
然而对于一连串数字并不方便记忆,于是节点还有可以帮组人们方便记忆的名称。比如
www.baidu.com。对于计算机节点来讲,一个名称指一个地址,但是名称并不锁定一个地址,如果你拥有多个节点地址,你可以让他都叫做这个名称。
对于
节点名称,我们更多叫它域名。(域名需要购买和备案的)
计算机在计算机网络中通信
计算机在网络中是通过包进行通信的。流经网络的数据备分割成很多个小块,我们将这些小块称为
包 (packet)。在通信中,我们将每个
包都单独加以处理,使
包中都包含
由谁发送和
将发往何处等的信息。
那么我们如何来处理
每个包呢? 为了解决这个问题,我们就定义了一些
协议,协议定义了计算机如何通信的一组明确的规则:
包括地址格式、数据如何分包等。
针对网络通信的不同方面,大家定义了很多不同的
协议。例如超文本传输协议
HTTP,定义了web浏览器何如与服务器通信。
在计算机网络中常用的协议有哪些?
协议 | 端口 | 基础协议 | 用途 |
---|---|---|---|
HTTP/HTTPS | 80 | TCP | 国际互联网的支持协议 |
file | TCP | 本地文件协议 | |
FTP | 21 | TCP | 文件传输协议 |
SSH | 22 | TCP | 用于加密和远程登录 |
SMTP | 25 | TCP | 邮件协议 |
talent | 23 | TCP | 用于交互式远程登录会话 |
网络协议的基础-TCP/IP
TCP/IP协议是网络的基础,是Internet的语言,可以说没有TCP/IP协议就没有互联网的今天。 TCP/IP是"Tramsmission Control Protocol/Internet Protocol"的简写,中文译名为 传输控制协议/互联网协议,TCP/IP协议是一种网络通信协议,它规范了网络上的所有通信设备,尤其是一个主机与另一个主机之间的数据往来格式以及传送方式。TCP/IP是INTENET的基础协议,也是一种电脑数据打包和寻址的标准方式。在数据传送中,可以形象地理解为有两个信封,TCP和IP就像是信封,要传递的信息被划分成若干段,每一段塞入一个TCP信封,并在该信封面上记录分段号的信息,再将TCP信封塞入IP大信封,发送上网。在接收端,一个TCP软件包收集信封,抽出数据,按发送前的顺序还原,并加一校验,若发现差错,TCP将会要求重发。因此,TCP/IP在INTERNET中几乎可以无差错地传送数据。对普通用户来说,并不需要了解网络协议的整个结构,仅需了解IP的地址格式,即可与世界各地进行网络通信。
关于TCP/IP的基础理论比较多,在此给大家推荐一个博客
NSURL
======================在计算机网络中常用的协议有哪些?
URL
URL用于标识Internet上资源位置。它指定用于访问服务器的协议、服务器名称以及文件自服务器上面的位置
如:http://3.chihuoyizu.sinaapp.com
语法:
protocol://username@hostname:port/path/filename?query#fragment
1.’
protocol‘:代表网络协议,可以http、FTP、file等协议
2.’
username‘:代表服务器用户名,可选参数
3.’
hostname‘:代表服务器名称,可以是名称,也可以是’节点地址’
4.’
port‘:代表端口号,可选参数,如果是http协议,会默认端口为80端口,如果是FTP协议,默认是21端口
5.’
path/filename‘代表文件在服务器路径
6.’
query#fragment‘:代表查询条件,通常用于向服务器提供附加参数,一般只用于http URL,这里的查询条件是向服务器程序提供参数。
note:在URL中不可以出现中文、空格、百分号等一些特殊字符串。因此我们需要对此URL进行编码
为什么要对url进行编码
我们都知道Http协议中参数的传输是"key = value"这种键值对形式的,如果要传多个参数就需要用"&"符号对键值对进行分割,如"?name1=value1&name2=value2",这样在服务端在收到这种字符串的时候,就会用"&"分割处每一个参数,然后再用"="来分割处参数值。 针对"name1=value1&name2=value2"我们来说一下客户端到服务器端的概念上解析过程: 上述字符串在计算机中用ASCII码表示为: 6E616D6531 3D 76616C756531 26 6E616D6532 3D 76616C756532。 6E616D6531:name1 3D:= 76616C756531:value1 26:& 6E616D6532:name2 3D:= 76616C756532:value2 服务端在接收到该数据后就可以遍历该字节流,首先一个字节一个字节的吃,当吃到3D这个字节后,服务端就知道前面吃的字节表示一个key,再向后吃,如果遇到26字节之间的是上一个key的value,以此类推就可以解析处客户端传过来的参数。 现在有这样一个问题,如果我都参数中就包含=或者&这种特殊字符的时候该怎么办。 比如说"name1=vale1",其中value1的值是"va&lu=e1"。我们的本意是就只有一个键值对,但是服务端会解析成两个键值对,这样就产生奇异。 如何解决上述问题带来的歧义呢?解决的办法就是对参数进行URL编码 URL编码只是简单的在特殊字符的各个字节前面加上%,例如,我们对上述会产生歧义的字符进行URL编码后结果:"va%26lu=e%3D",这样服务端会把紧跟在"%"后的字节当成普通的字节,就是不会把它当成各个参数或键值对的分割符。
在OC中使用NSURL
类来定义URL
//将url字符串转成NSURL类 NSURL *url = [NSURL URLWithString:@"http://iosseventeenclass.sinaapp.com/index.php?name=vincent&age=25"]; //用NSData接收从服务器端传过来的数据 NSData *data = [NSData dataWithContentsOfURL:url]; //将data转成字符串输出 NSString *string = [[NSString alloc] initWithData:data encoding:4]; NSLog(@"string = %@",string);
有时候我们传入给服务器的参数出现中文,但是URL不支持中文等一些特殊的字符,那么此时需要进行url编码
NSString *urlString = @"http://iosseventeenclass.sinaapp.com/index.php?name=林福荣&age=25"; //将url字符串进行编码 urlString = [urlString stringByAddingPercentEscapesUsingEncoding:4]; //将url字符串转成NSURL类 NSURL *url = [NSURL URLWithString:urlString]; //用NSData接收从服务器端传过来的数据 NSData *data = [NSData dataWithContentsOfURL:url]; //将data转成字符串输出 NSString *string = [[NSString alloc] initWithData:data encoding:4]; NSLog(@"string = %@",string);
在OC中将URL字符串转换成NSURL时,其协议、主机域名、路径文件、查询条件都被封装成NSURL类中的属性,如下示:
//转码后的urlString NSLog(@"url2.absoluteString =%@",url2.absoluteString); //协议 NSLog(@"url2.scheme = %@",url2.scheme); NSLog(@"url2.resourceSpecifier = %@",url2.resourceSpecifier); //服务器名称 NSLog(@"url2.host = %@",url2.host); //端口 NSLog(@"url2.port = %@",url2.port); //服务器用户名 NSLog(@"url2.user = %@",url2.user); //密码 NSLog(@"url2.password = %@",url2.password);
GET和POST
在iOS开发中,我们的客户端即iPhone和服务器端数据交互常用的方式有两种,GET请求和POST请求。当然还有一些请求方式,如 PUT 、 DELETE等。此节课主要是给大家讲解GET和POST请求 1.GET请求 GET请求是客户端向服务器端请求资源 2.POST请求 POST请求是客户端向服务器端上传资源 note: HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
GET和POST请求的报文格式
我们这里讲到的GET和
POST请求是基于
HTTP协议之下,在
HTTP协议下,对于
GET和
POST请求,它们都有规定的请求格式。
HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的。HTTP有两类报文:请求报文和响应报文。
1.请求报文
一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成,下图给出了请求报文的一般格式。 (1)请求行 请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。 (2)请求头部 请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息。 典型的请求头有: User-Agent:产生请求的浏览器类型。 Accept:客户端可识别的内容类型列表。 Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。 (3)空行 最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。 对于一个完整的http请求来说空行是必须的,否则服务器会认为本次请求的数据尚未完全发送到服务器,处于等待状态。 (4)请求数据 请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。 (5)请求示例 POST: POST报文头如下: POST /sn/index.php HTTP/1.1 Accept: */* Accept-Language: zh-cn host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 12 Connection:close sn=123&n=asa 在http头后边有一空行,空行后边接着发送post数据,长度通过Content-Length: 12指出, 此post数据中包含两项: sn=123 n=asa 其中: Content-Type: application/x-www-form-urlencoded 指定POST数据的编码类型 Content-Length: 12 POST数据的长度 GET: GET报问头如下: GET /sn/index.php?sn=123&n=asa HTTP/1.1 Accept: */* Accept-Language: zh-cn host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 12 Connection:close
使用OC进行实现GET和POST请求
===================同步get 与 异步get
同步get 与 同步 Post 都会卡 UI微博同步get方法:前面4步与异步get是一样的; 1.首先拿到一个字符串:(微博url?Token); NSString *urlString = @"https://api.weibo.com/2/statuses/home_timeline.json?access_token=2.00UjS1zBGCFBqD667c9bd9e6UuDfND"; 2.对字符串编码(避免字符串中有特殊符号); urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; 3.将转码好的字符串转成NSUrl类(网址); NSURL *url = [NSURL URLWithString: urlString]; 4.创建并返回一个url请求,批向一个指定的url,采用对应的缓存策略 和 超时相应时长(默认时长 为60秒); NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10]; 5.将请求回来的数据和服务器进行同步连接(即转化成Data数据); NSURLResponse *httpUrlResponse; NSError *error; //在OC中使用NSURLConnection类,和服务器连接,这里是同步连接 NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&httpUrlResponse error:&error ]; 6.将Data数据进行Json解析,并封装成字典; NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; 7.建立一个微博模型,并将字典初始化模型; WeiBoModel *weibo = [[WeiBoModel alloc] initWithDictionary:dictionary]; 8.将最后得出结果写在UI上.
self.ffff.text = [weibo.statuses[0] objectForKey:@”text”];
微博异步get方法 1.首先拿到一个字符串:(微博url?Token); NSString *urlString = @"https://api.weibo.com/2/statuses/home_timeline.json?access_token=2.00UjS1zBGCFBqD667c9bd9e6UuDfND"; 2.对字符串编码(避免字符串中有特殊符号); urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; 3.将转码好的字符串转成NSUrl类(网址); NSURL *url = [NSURL URLWithString: urlString]; 4.创建并返回一个url请求,批向一个指定的url,采用对应的缓存策略 和 超时相应时长 (默认时长 为60秒) NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10]; 异步请求有两种方式:一种是使用代理,一种是使用block 5.1使用代理; NSURLConnection *connentGet = [NSURLConnection connectionWithRequest:request delegate:self]; 5.2使用block请求连接并转成data [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { 6.将请求回来的数据和服务器进行同步连接(即转化成Data数据); NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; 7.建立一个微博模型,并将字典初始化模型; WeiBoModel *weibo = [[WeiBoModel alloc]initWithDictionary:dictionary]; 8.将最后得出的结果写成UI上; dispatch_async( dispatch_get_main_queue(), ^{ self.ffff.text = [weibo.statuses[0] objectForKey:@"text"];
同步Post 与 异步Post
微博同步Post方法: 1.拿到一个字符串:(发送一条微博的URL地址); NSString *urlString =@"https://api.weibo.com/2/statuses/update.json"; 2.对字符串编码(避免字符串中有特殊符号); urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]; 3.将转码好的字符串转成NSUrl类(网址); NSURL *url = [NSURL URLWithString:urlString]; 4.创建一个请求,OC中使用NSMutableURLRequest进行POST请求 NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60]; 5.创建一个Token字符串,将要发表的内容写在 status= 与 &access 之间; NSString *bodyString = @"status=人生不过是一场旅行,你路过我,我路过你,然后,各自修行,各自向前。&access_token=2.00UjS1zBGCFBqD667c9bd9e6UuDfND"; 6.将这个要发表的字符串内容转码成Data数据形式; NSData *data = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; 7.设置方法体(有了要发表的内容Data后,再声明发送请求,发送内容为data); [mRequest setHTTPMethod:@"POST"]; [mRequest setHTTPBody:data]; 8.请求连接 NSData *resultData = [NSURLConnection sendSynchronousRequest:mRequest returningResponse:nil error:nil]; 9.转换成json:// 发布的话这一步可以不用解析.但是get就要解析.因为网络会自动将data数据进行解析后再发送. NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:resultData options:NSJSONReadingAllowFragments error:nil]; NSLog(@"dictionary = %@",dictionary);
===========================================================
微博异步Post方法:前面7步与同步Post是一样的;
1.拿到一个字符串:(发送一条微博的URL地址); NSString *urlString =@"https://api.weibo.com/2/statuses/update.json"; 2.对字符串编码(避免字符串中有特殊符号); urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]; 3.将转码好的字符串转成NSUrl类(网址); NSURL *url = [NSURL URLWithString:urlString]; 4.创建一个请求,OC中使用NSMutableURLRequest进行POST请求 NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60]; 5.创建一个Token字符串,将要发表的内容写在 status= 与 &access 之间; NSString *bodyString = @"status=人生不过是一场旅行,你路过我,我路过你,然后,各自修行,各自向前。&access_token=2.00UjS1zBGCFBqD667c9bd9e6UuDfND"; 6.将这个要发表的字符串内容转码成Data数据形式; NSData *data = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; 7.设置方法体(有了要发表的内容Data后,再声明发送请求,发送内容为data); [mRequest setHTTPMethod:@"POST"]; [mRequest setHTTPBody:data]; 8.请求连接:使用代理 NSURLConnection *connectionPost = [NSURLConnection connectionWithRequest:mAsynRequest delegate:self];
==================================
代理部分:
//服务器开始响应,准备向客户发送数据
-(void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse )response
{
NSLog(@”服务器开始响应,准备向客户发送数据”);
if (connection == connentGet) { mData = [NSMutableData data]; } if (connection == connectionPost) { mPostData = [NSMutableData data]; } } //从服务器接收数据,并且此方法会执行很多次 -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { NSLog(@"从服务器接收数据,并且此方法会执行很多次"); if (connection == connentGet) { [mData appendData:data]; } if (connection == connectionPost) { [mPostData appendData:data]; } } //接收数据完成 -(void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"接收数据完成"); if (connection == connentGet) { NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:mData options:NSJSONReadingAllowFragments error:nil];//接收完数据后使用Json解析工具解析mData WeiBoModel *weibo = [[WeiBoModel alloc]initWithDictionary:dictionary]; // [self.ffff performSelectorOnMainThread:@selector(setText:) withObject:[weibo.statuses[0] objectForKey:@"text"] waitUntilDone:NO]; // self.ffff.text = [weibo.statuses[0] objectForKey:@"text"]; /* 更新UI最好在主线程中更新,原因如下: 1.在子线程中是不能进行UI更新的,而可以更新的结果只是一个幻想:因为子线程代码执行完毕,又自动进入到主线程,执行了主线程中的UI更新的函数栈,这中间的时间非常短,就让大家误以为子线程可以更新UI.如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新. 2.只有极少数的UI能,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方式是开辟一个子线程,在子线程中对该按钮进行UI更新是能及时的,如换标题,换背景图,但是这没有任何意义. */ } if (connection == connectionPost) { NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:mPostData options:NSJSONReadingAllowFragments error:nil]; NSLog(@"dic = %@",dic); } }
==========================
字符串 url 编码 Data
//有那么一个字符串 NSString *newStr = @"www.baidu你妹.com"; //普通字符串,(当然也可以看作是一个地址) //转成data传输到另一地 NSData *dat = [newStr dataUsingEncoding:NSUTF8StringEncoding]; //还原(原来字符串是什么样就得回什么样) NSString *newStrLata = [[NSString alloc] initWithData:dat encoding:NSUTF8StringEncoding]; NSLog(@"newStrLata = %@",newStrLata); newStrLata = www.baidu你妹.com
//urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//stringByAddingPercentEscapesUsingEncoding(只对 `#%^{}[]|\”<> 加空格共14个字符编码,不包括”&?”等符号), ios9将淘汰,建议用stringByAddingPercentEncodingWithAllowedCharacters方法
//有那么一个地址字符串 NSString *newStr2 = @"http://www.baidu.com"; //现在想要传输这个地址上的内容到另一地 //编码(避免有特殊字符存在)(这个必有http://开头才为网络地址.) newStr2 = [newStr2 stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]; //转成url,一个地址, NSURL *newStr2Url = [NSURL URLWithString:newStr2]; //转成data,让data读取这个地址上的内容并将其转成data数据 NSData *newStr2UrlData = [NSData dataWithContentsOfURL:newStr2Url]; //将读取到的Data内容传输给另一方(还原成string(但是是内空还原,不是地址还原)) NSString *newStr2UrlDataLate = [[NSString alloc] initWithData:newStr2UrlData encoding:NSUTF8StringEncoding]; NSLog(@"newStr2UrlDataLate = %@",newStr2UrlDataLate); //将读取到的Data内容写入到本地一个指定文件 BOOL newflag = [newStr2UrlData writeToFile:@"/Users/ibokan/Desktop/baidu.html" atomically:YES]; if (newflag) { NSLog(@"success"); }
相关文章推荐
- 网络字节序和本机字节序
- Http请求中的Content-Type
- TCP状态变迁图
- TCP/IP详解--发送ACK和RST的场景
- 通过HttpURLConnection模拟post表单提交
- TCP/IP详解--连接状态变迁图CLOSE_WAIT
- Linux内核工程导论——网络:Netfilter概览
- PageRank:核心算法|谷歌如何从网络的大海里捞到针
- 安装Eclipse https://tools.hana.ondemand.com/#abap
- libnids中TCP/IP栈实现细节分析(下)——IP分片重组
- linux网络编程
- ubuntu 网络设置
- http://www.th7.cn/Program/Android/201501/351050.shtml
- 写给后端程序员的HTTP缓存原理介绍
- Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
- 使用 HTTP 缓存机制提升系统性能
- iOS开发之-- DNS解析(网络切换的问题解决)
- 深入理解HTTP协议、HTTP协议原理分析
- HttpClient 教程 (一)
- Python 网络编程之UDP