ios基础篇(十六)—— 网络之sockct

el/2023/6/4 14:40:23

一、网络基本概念

  • 客户端:应用  C/S   B/S
  • 服务器:为客户端提供服务、数据、资源的机器
  • 请求:客户端向服务器索取数据
  • 响应:服务器对客户端的请求作出反应,一般是返回给客户端数据
  • 服务器
    • 内网服务器
    • 外网服务器
    • 本地测试服务器

二、URL

  • 准备获取网络上的资源,首先要了解URL
  • 什么是URL
    • Uniform Resource Locator(统一资源定位符)
    • 网络中每一个资源都对应唯一的地址—URL
  • URL的基本格式
    • 协议://主机地址:端口号/路径

协议: 不同的协议代表不同的资源获取方式

主机地址:主机的唯一标示(IP地址、域名)

路径:资源在主机中的具体位置

    • 举例:
      • http://www.itheima.com/
      • http://www.itheima.com/images/xx00.png
      • ftp://www.itheima.com/movies/cls.avi
  • URL的常见协议
    • HTTP、FTP、mailto、File、tel://、sms://

三、HTTP协议简介

  • 什么是协议
    • 双方规定好的约定
  • 什么是HTTP协议
    • HyperText Transport Protocol(超文本传输协议)
    • 浏览器和Web服务器通讯时候遵守的约定
    • 互联网使用最多的协议
    • 提供超文本传输服务
    • 通过浏览器打开网站使用的就是HTTP提供的服务,开发App也会经常使用HTTP协议从网络上获取数据
  • 通过浏览器打开网站使用的就是http提供的服务
    • 开发app,也会经常使用http协议从网络上获取数据
  • 请求-响应

HTTP请求演示

  • 演示请求百度首页
  • 代码
//1 创建请求的地址NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];//2 创建请求对象,告诉服务器一些信息NSURLRequest *request = [NSURLRequest requestWithURL:url];//3 建立网络连接,向服务器发送请求,并接收服务器返回的响应[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {//网络请求完成后执行的方法//NSURLResponse *response,  服务器返回的响应对象//NSData *data,             服务器返回的二进制数据//NSError *connectionError  如果错误,返回的错误信息
//        NSLog(@"%@",data);
//        [data writeToFile:@"/Users/你的用户名/Desktop/123.html" atomically:YES];//把二进制数据 转换成字符串NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];NSLog(@"%@",str);}];
  • Xcode7中的ATS
    • ATS(App Transport Security) 默认禁止发送HTTP请求
<key>NSAppTransportSecurity</key>
<dict><key>NSAllowsArbitraryLoads</key><true/>
</dict>

三、IP地址

  • 两个计算机通讯必须要知道的
    • IP地址和端口号
  • IP地址
    • IP地址是一个32位的二进制数,通常被分割为8位二进制数,通常用点分10进制表示
      • 192.168.1.1
      • 127.0.0.1   回环地址(本机地址)    255.255.255.255  广播      0.0.0.0  any
    • 唯一标示互联网上的一台计算机(ip地址不好记忆,所以有了域名)
    • 一个计算机可能有多个可用的ip地址,比如:两块网卡(集成网卡和无线网卡)
    • 内网的计算机,都通过路由器上网。他们对外的地址都是路由器的ip地址

四、端口号

  • 端口号
    • 标示进程(程序)的逻辑地址,不同进程(程序)的标示
    • 端口取值范围:0~65535
    • 端口的分类
      • 公认端口(Well Known Ports)
        • 这类端口也常称之为”常用端口"。这类端口的端口号从0到1024,它们紧密绑定于一些特定的服务。通常这些端口的通信明确表明了某种服务的协议,这种端口是不可再重新定义它的作用对象。比如:http默认80,ftp默认21  pop3 110  smtp 25
      • 注册端口(Registered Ports)
        • 端口号从1025到49151。分配给用户进程或应用程序。这些进程主要是用户选择安装的一些应用程序,而不是已经分配好了公认端口的常用程序。
      • 动态和/或私有端口(Dynamic and/or Private Ports)
        • 端口号从49152到65535。之所以称为动态端口,是因为它 一般不固定分配某种服务,而是动态分配

五、网络模型

  • OSI七层网络模型
    • 应用层
    • 表示层
    • 会话层
    • 传输层
    • 网络层
    • 数据链路层
    • 物理层

六、TCP/IP网络模型

  • 应用层
    • 对应OSI模型的前三层,为用户提供所需的各种服务,例如:FTP、Telnet、DNS、SMTP、HTTP等
  • 传输层
    • 为应用层提供端到端的通信功能,保证了数据包的传输顺序及数据完整性。两个主要协议:TCP和UDP
  • 网络层
    • 解决主机到主机的通信问题。它所保护的协议设计数据包在整个网络上的逻辑传输。注重重新赋予主机一个IP地址来完成对主机的寻址,它还负责数据包在多种网络中的路由。该层有三个主要协议:网际协议(IP)、互联网组管理协议(IGMP)和互联网控制报文协议(ICMP)。
  • 网络接入层
    • 负责监视数据在主机和网络之间的交换

       

TCP/UDP报文

IP报文

七、传输协议

  • TCP(传输控制协议)
    • TCP协议提供的是一种可靠的、通过“三次握手”来连接的数据传输服务
  • UDP(用户数据报协议)
    • UDP协议提供的则是不保证可靠性(并不是不可靠)、无连接的数据传输服务

八、Socket

  • 两个计算机通讯的过程,就像两个人打电话一样
  • Socket
    • Socket又称“套接字”,应用程序通过“套接字”向网络发送请求或向网络做出应答
    • 网络通信其实就是Socket之间的通信
    • 数据在两个Socket之间通过IO传输数据
    • Socket是纯C语言的,是跨平台的
    • HTTP协议是基于Socket的,HTTP协议的底层使用的就是Socket

Socket的通信过程

  • 创建Socket
  • 连接到服务器
  • 发送数据给服务器
  • 从服务器接收数据
  • 关闭连接

Socket的创建

导入头文件
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
创建Socket
int socket(int domain, int type, int protocol);//参数1 domain  协议域 AF_INET--IPV4//参数2 type    socket类型 SOCK_STREAM(TCP)/SOCKET_DGRAM(UDP)//参数3 protocol  IPPROTO_TCP/IPPROTO_UDP   如果 传入0 会根据第二个参数选择合适的    //返回值 >0  创建成功 socket的描述符示例:int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

连接服务器

打开Netcat,模拟服务器
打开终端
nc -lk 12345
nc-->Netcat  终端下用于调试和检查网络的工具
连接服务器
int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);
//参数1 sockfd     客户端socket//参数2 serv_addr  服务器地址结构体指针//参数3 addrlen    结构体数据长度//返回值  成功则返回0,失败返回非0示例:
//返回值  成功则返回0,失败返回非0struct sockaddr_in serverAddr;//IPV4serverAddr.sin_family = AF_INET;//端口serverAddr.sin_port = htons(12345);//ip地址serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");int connResult = connect(clientSocket, (const struct sockaddr *)&serverAddr, sizeof(serverAddr));if (connResult == 0) {NSLog(@"连接成功");}else{NSLog(@"连接失败");}

Socket收发数据

发送数据给服务器
const char *sendMessage = "hello world";ssize_t sendLen = send(clientSocket, sendMessage, strlen(sendMessage), 0);NSLog(@"发送的字节数:%ld",sendLen);
接收服务器返回的数据
uint8_t buffer[1024];
ssize_t recvLen = recv(clientSocket, buffer, sizeof(buffer), 0);if (recvLen > 0) {NSLog(@"接收了%ld个字节",recvLen);//从缓冲区读取数据NSData *data = [NSData dataWithBytes:buffer length:recvLen];NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];NSLog(@"%@",msg);}
关闭连接close(clientSocket);

请求百度

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end@implementation ViewController
- (void)viewDidLoad {[super viewDidLoad];   //发送请求NSURL *url = [NSURL URLWithString:@"https://m.baidu.com"];//请求NSURLRequest *request = [NSURLRequest requestWithURL:url];//发送异步请求[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue  mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {//response  服务器返回的响应头//data      服务器返回的响应体//connectionError  连接错误//判断请求是否有错误if (!connectionError) {//把二进制数据转换成NSStringNSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];NSLog(@"%@",html);           //webView加载html[self.webView loadHTMLString:html baseURL:nil];}else{NSLog(@"连接错误 %@",connectionError);}}];
}

socket 请求百度

#import "ViewController.h"
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (nonatomic, assign) int clientSocket;
@end@implementation ViewController
- (void)viewDidLoad {[super viewDidLoad];//1 连接百度的服务器BOOL result = [self connect:@"61.135.169.125" port:80];if (!result) {NSLog(@"连接失败");return;}NSLog(@"连接成功");//构造http请求头NSString *request = @"GET / HTTP/1.1\r\n""Host: www.baidu.com\r\n""User-Agent: Mozilla/5.0 (Linux; Android 4.0.3; HTC One X Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19\r\n""Connection: keep-alive\r\n\r\n";  //http/1.0  短连接  当响应结束后连接会立即断开//http/1.1  长连接  当响应结束后,连接会等待非常短的时间,如果这个时间内没有新的请求,就断开连接//服务器返回的响应头 和 响应体NSString *respose = [self sendAndRecv:request];NSLog(@"----%@",respose);//关闭连接  http协议要求,请求结束后要关闭连接close(self.clientSocket); //截取响应头   响应头结束的表示\r\n\r\n<!   //找到\r\n\r\n 的范围NSRange range = [respose rangeOfString:@"\r\n\r\n"];//从\r\n\r\n之后的第一个位置开始截取字符串  响应体NSString *html = [respose substringFromIndex:range.length + range.location ];[self.webView loadHTMLString:html baseURL:[NSURL URLWithString:@"http://www.baidu.com"]];}
//1 连接服务器
- (BOOL)connect:(NSString *)ip port:(int)port{int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);self.clientSocket = clientSocket;struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(ip.UTF8String);addr.sin_port = htons(port);int result = connect(clientSocket, (const struct sockaddr *) &addr, sizeof(addr));if (result == 0) {return YES;}else{return NO;}
}
//2 发送和接收数据
- (NSString *)sendAndRecv:(NSString *)sendMsg {//3 向服务器发送数据//成功则返回实际传送出去的字符数,失败返回-1const char *msg = sendMsg.UTF8String;ssize_t sendCount = send(self.clientSocket, msg, strlen(msg), 0);NSLog(@"发送的字节数 %zd",sendCount);    //4 接收服务器返回的数据//返回的是实际接收的字节个数uint8_t buffer[1024];    NSMutableData *mData = [NSMutableData data];ssize_t recvCount = recv(self.clientSocket, buffer, sizeof(buffer), 0);;[mData appendBytes:buffer length:recvCount];    //服务器会返回多次数据,等所有的数据都接收完成,再转换成字符串while (recvCount != 0) {recvCount = recv(self.clientSocket, buffer, sizeof(buffer), 0);NSLog(@"接收的字节数 %zd",recvCount);[mData appendBytes:buffer length:recvCount];}    //把字节数组转换成字符串NSString *recvMsg = [[NSString alloc] initWithData:mData.copy encoding:NSUTF8StringEncoding];return recvMsg;
}

 

http://www.ngui.cc/el/3419339.html

相关文章

时序图

一、时序图简介&#xff08;Brief introduction&#xff09; 时序图&#xff08;Sequence Diagram&#xff09;是显示对象之间交互的图&#xff0c;这些对象是按时间顺序排列的。 顺序图中显示的是参与交互的对象及其对象之间消息交互的顺序。 时序图中包括的建模元素主要有&a…

《Objective-C高级编程:iOS与OS X多线程和内存管理》 一 自动引用计数

一、自动引用计数 1.1 内存管理的思考方式 对象操作与objective-c 方法的对应对象操作Object-C 方法生成并持有对象alloc、new、copy、mutableCopy持有对象retain方法释放对象release方法废弃对象dealloc方法1.1.1 自己生成的对象&#xff0c;自己持有 使用以下名称开头的方…

《Objective-C高级编程:iOS与OS X多线程和内存管理》 一 Blocks模式GCD

一、Blocks摘要 Blocks&#xff1a;带有自动变量&#xff08;局部变量&#xff09;的匿名函数。 匿名函数&#xff1a;不带有名称的函数。 int func(int cout); //声明名称为func的函数 int result func(10); // 调用该函数&#xff0c;必须使用该函数的名称 // 若像下面这…

JXCategoryTitleView的使用

最近写项目&#xff0c;遇到了一个vc下面有多个vc 指示器可以点击切换&#xff0c;也可也左右滑动进行切换&#xff0c;解除了JXCategoryTitleView 感觉很好用&#xff1b; 一般要求主vc遵循JXCategoryViewDelegate、JXCategoryListContainerViewDelegate两个协议 子vc遵循JX…

基本编程能力练习

一、首先下载Java的编译环境并安装 JDK下载地址&#xff1a;https://www.oracle.com/java/technologies/javase-jdk15-downloads.html 选择适合自己系统的版本进行安装 这里我选择的是jdk-15_windows-x64_bin.exe 下载完成后直接运行安装&#xff0c;安装位置选择默认的C盘&am…

基本任务1.1Java语言基础

一、任务要求 完成基本数据类型的使用。完成基本运算符和表达式的使用。完成基本控制语句&#xff1a;判断、分支、循环等语句的使用。完成数组的使用。所有源代码必须加入行一级注释。 二、任务的理解 本次任务是让我们对Java编程中所遇到的基础知识进行学习和掌握&#xf…

基本任务1.1Java语言基础(任务挑战)

任务挑战&#xff1a; 1.编制一个Java application应用程序&#xff0c;把数组中已知的10个数字由小到大排序后输出。 编程前思考&#xff1a; 完成数组排序的方法有多种&#xff0c;其中有调用Arrays类中的sort方法直接对数组进行由小到大的排序&#xff0c;还可以采用冒泡排序…

基本任务1.2Java面向对象程序

一、任务要求 完成一个Java application应用程序&#xff0c;描述一个人类。要求如下&#xff1a;要求此人类必须包含有人的姓名、性别、出生日期等基本属性&#xff08;变量&#xff09;。要求此人类描述吃饭的方法&#xff08;函数&#xff09;和描述睡觉的方法&#xff08;…

基本任务1.3Java API

完成一个 java application应用程序&#xff0c;可以接收用户通过键盘输入的文本&#xff0c;并输出此段文本字符的个数。 代码&#xff1a; package task; //包名 import java.util.Scanner; //导入Scanner类 public class JavaAPI { //创建类public static void…

Tensorflow的安装与配置

Tensorflow的安装与配置 经过多次的安装失败&#xff0c;找寻原因&#xff0c;最终安装成功。 1、基于之前安装的anaconda的基础上进行tensorflow的安装&#xff0c;首先通过按windows键和R键弹出运行框&#xff0c;输入CMD回车&#xff0c;进入cmd命令窗口&#xff0c;先查询…