网络编程

来源:互联网 发布:手机编辑音频软件 编辑:程序博客网 时间:2024/05/16 10:07

软件系统架构两种方式

B / S: Browser / Server (Web浏览器 + Web服务器)

C / S: Client / Server (客户端 + 服务器)

服务器:

FTP服务器(File Transport Protocol)

Web服务器:提供各种网页请求的服务的机器

域名和IP地址的关系(Web浏览器和服务器流程)?

Web浏览器输入域名(发送请求html主页)-> DNS服务器(域名和IP映射)-> IP地址 -> 找到Web服务器 -> 服务器响应(返回请求的主页) -> Web浏览器解析并显示主页(解析html文档,再显示)

样例:把本地的Mac机器变成Web服务器(提供响应html文档服务的机器)

 1. 启动Mac已经支持的Apache软件, 终端执行命令

    sudo apachectl start

2. 验证:浏览器编辑框中输入  localhost

   -》 看到It works!, 启动成功

3. 找到It works对应的html的路径

    /Library/WebServer/Documents/index.html.en

4. 浏览器输入框输入 localhost(本机机器的名字)

    -> 输入 172.60.50.87 (本机的IP地址)

  -> 172.60.50.87/index.html (默认主页一般都是index.html)

  -> 172.60.50.87:80/index.html (默认Web服务器的端口号是80)


端口号port是什么?什么作用?

标识网络应用的逻辑地址;唯一

端口号格式: 1~65535

1 ~ 255被占用:80被Web服务占用;21被FTP服务占用;23被email服务占用

256 ~ 1023被占用:Unix进程占用

1024 ~ 65535:可使用


网络中的三要素:IP地址 + 端口号 + 协议

URL(Uniform Resource Locator:统一资源定位符)

1.作用:找到某台服务器的资源(html主页;图片;音频文件...)

2.格式:协议://域名:端口号/路径/资源名字

http://172.60.50.87:80/index.html

http://172.60.50.87:80/image/test.png

3.常用协议:

a.file协议:本地规定数据传输的协议

file:///Users/lightning111/Library/image/test.png

4.本地URL;还是远程URL

本地URL(NSString -> NSURL):[NSURL fileURLWithString:xxx];

远程URL(NSString -> NSURL):[NSURL urlWithString:@"http://www.baidu.com"];

分析:

1. iPhone模拟器看到的百度主页和Mac浏览器看到的界面不一样

  -> 对移动端又开发一套主页m.baidu.com

  -> 对桌面又开发另一套主页www.baidu.com

2. 响应式编程(Response....): 根据设备不同的分辨率推送不同样式/页面的方式

3. 如果输入https://www.baidu.com,无法显示主页;原因是百度的https和苹果要求的https的证书不太一样


DNS: Domain Name System/Service; 找域名和IP地址关系

[Demo01_UIWebView]

<span style="font-size:14px;">@interface ViewController ()<UIWebViewDelegate>@property (weak, nonatomic) IBOutlet UIWebView *webView;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    //1.创建远程NSURL对象;指定请求的url    NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];    //2.创建NSURLRequest对象    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];    //2.1 设置代理    self.webView.delegate = self;    //3.使用webView对象加载请求    [self.webView loadRequest:request];}//开始加载- (void)webViewDidStartLoad:(UIWebView *)webView{    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];}//成功加载完毕- (void)webViewDidFinishLoad:(UIWebView *)webView{    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];}//失败返回- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error{    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];    NSLog(@"请求百度主页失败:%@", error.userInfo);}</span>


UIWebView和WKWebView的区别

UIWebView能做什么?

1. 加载本地/远程HTML文档

2. 导航上一个或者下一个web页面

3. 运行基本/简单的JavaScript


WKWebView能做什么?

1. iOS8引入的控件;WebKit Framework; 完全可以替代UIWebView

2. iOS和Mac两个平台的统一控件

3. 响应速度60fps(Frame Per Second)

4. 占用内存是UIWebView的1/3 ~ 1/4

5. 可以运行较复杂的JavaScript


样例(理解):使用WKWebView加载百度主页

 【Demo02_WKWebView】

1. WKWebView只能用代码创建添加

2. WKNavigationDelegate

<span style="font-size:14px;">- (void)viewDidLoad {    [super viewDidLoad];        //1.创建NSURL    NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];    //2.创建NSURLRequest    NSURLRequest *request = [NSURLRequest requestWithURL:url];    //3.创建WKWebView对象,添加到界面(storyboard没有控件)    WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame];    [self.view addSubview:webView];    //3.1 设置代理    webView.navigationDelegate = self;    //4.加载请求    [webView loadRequest:request];}//开始加载- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];}//加载成功- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];}//加载失败- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];    NSLog(@"百度主页加载失败:%@", error.userInfo);    }</span>



Socket通信是什么?

什么是Socket(插孔/插座)?

两个网络程序通过一个双向的通信连接实现数据交换的过程


如何实现Socket聊天功能(局域网内)?

三个步骤:

1. 服务器处于监听状态(机器开机+软件启动) -> 端口打开

2.客户端发送Socket连接(成功:发送数据通道打开; 失败:无法发送数据)

3.发送数据; 接收数据


网络层(从上到下):

应用层协议:HTTP/HTTPS; FTP; XMPP;

  Socket(接口:发送/接收数据; 连接)

数据传输层协议:TCP/UDP


样例:实现Socket聊天功能(局域网内)

  【Demo03_Socket】

 -> 第三方封装原生的Socket接口

 -> 客户端的界面:

      UITextField: IP; UIButton:连接; UITextField(消息);UIButton(发送消息); UITextView(显示服务器端的消息)

 -> 如何执行发送聊天的功能(步骤)

    1. 一个同学做服务器端,只要启动AsyncSocket-Server工程即可

    2. 另一个同学做客户端,启动Demo03_Socket项目,在界面上输入对方的ip

    3. 点击“连接对方机器”的按钮,直到在终端看到“连接成功!!!!!!!!”为止

    4. 此时双方可以分别发送消息,分别在双方的UITextView显示消息


了解:CFNetwork实现/封装的Socket接口(输入流和输出流Stream)

ViewController.m

<span style="font-size:14px;">#import "ViewController.h"#import "GCDAsyncSocket.h"@interface ViewController ()<GCDAsyncSocketDelegate>@property (weak, nonatomic) IBOutlet UITextField *ipTextField;//发送消息@property (weak, nonatomic) IBOutlet UITextField *sendMsgTextField;//显示消息@property (weak, nonatomic) IBOutlet UITextView *showMsgTextView;//发送端的socket对象@property (nonatomic, strong) GCDAsyncSocket *clientSocket;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];}//连接到主机(宿主机)- (IBAction)connectToHost:(id)sender {    //初始化socket对象    self.clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];    //指定ip+port,开始建立连接    NSError *error = nil;    [self.clientSocket connectToHost:self.ipTextField.text onPort:8888 withTimeout:-1 error:&error];    if (!error) {        NSLog(@"正在连接中.....");    } else {        NSLog(@"客户端无法连接:%@", error.userInfo);    }}//发送消息到主机(写入输入流)- (IBAction)sendMsgToHost:(id)sender {    [self.clientSocket writeData:[self.sendMsgTextField.text dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];}//连接成功- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {    NSLog(@"连接成功!!!!!!!!");        //处于等待接收数据状态    [self.clientSocket readDataWithTimeout:-1 tag:0];}//客户端发送成功- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {    NSLog(@"客户端发送成功.....");}//接收另一端发送来的消息(从输出流读数据)- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {    NSString *readStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];    self.showMsgTextView.text = [NSString stringWithFormat:@"%@\n%@", self.showMsgTextView.text, readStr];    //处于等待接收数据状态    [self.clientSocket readDataWithTimeout:-1 tag:0];}</span>

导入GCDAsyncSocket.m



HTTP协议(Hyper Text Transfer Protocol:超文本传输协议)

超文本: 不仅包含简单的文本, 还包含图片, 音频/视频(第一帧图片Frame)

用于从服务器传输超文本到本地浏览器的传输协议,规定客户端(浏览器)和服务器之间的数据传输格式。


协议的具体内容(理解) -> 格式:key/value

第一部分:请求部分(浏览器请求资源)

  a. 请求头(Request Header)

  b. 请求体(Request Body)

第二部分:响应部分(服务器返回资源)

 a. 响应头(Response Header)

 b. 响应体(Response Body)

  Content-Length: 请求的资源的总大小(更新下载进度)

  状态码: 200:成功;404:资源找不到


MIME类型: 指定客户端接收的类型(主类型/子类型)

MIME: 

文件:text/html; text/xml; text/plain…

图片:  image/png; image/gif; image/jpeg…

文档:application/pdf; application/rtf…


HTTP协议四个方法:

GET: 获取资源请求; 如果不指定请求的方法,默认就是GET

POST: 一般发送带参数的请求叫POST请求

PUT: 一般上传资源叫PUT请求

DELETE:删除指定的资源


例子:登录,发送用户名和密码两个参数;

选择一: http://www.pech.com/post/login?username=gaoyuanyuan&password=123123123

选择二:两个参数放到请求体中(相对安全)


2. NSURLConnection(过时) / NSURLSession


样例(理解):使用NSURLConnection请求百度主页

 【Demo04_NSURLConnection】

 掌握点:如何用代码获取状态码(200: 成功)

 NSInteger statusCode = [(NSHTTPURLResponse *)responsestatusCode];

 理解:涉及到HTTP协议MIME这个key

 界面:UIButton+UIWebView+UITextField

<span style="font-size:14px;">#import "ViewController.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIWebView *webView;@property (weak, nonatomic) IBOutlet UITextField *urlTextField;@end@implementation ViewController- (IBAction)sendRequest:(id)sender {    //1.NSURL对象    NSURL *url = [NSURL URLWithString:self.urlTextField.text];    //2.NSURLRequest对象    NSURLRequest *request = [NSURLRequest requestWithURL:url];    //3.发送请求(NSURLConnection)    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {        //主线程执行        //从response对象中获取状态码Status code        NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];        if (statusCode == 200) {            //成功返回请求的主页数据data; 加载到webView            [self.webView loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:[NSURL fileURLWithPath:@"sdfs"]];        }    }];}</span>


0 0