iOS开发轻松学习Socket
theme: vuepress highlight: a11y-light
本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
这两天很多学员都想听听关于
Socket
的内容! 所以花了一点时间就给它备了出来,公开课分享完全足够了!
这里通过文字形式纪录下来,方便大家对应学习
Socket是什么?
要了解什么是 Socket
,首先需要了解 TCP/IP、UDP
! 📚
TCP/IP(Transmission Control Protocol/Internet Protocol)
即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。UDP(User Data Protocol,用户数据报协议)
是与TCP相对应的协议。它是属于TCP/IP
协议族中的一种。
TCP/IP协议族
包括运输层、网络层、链路层。现在你知道TCP/IP与UDP的关系了吧。
如果大家对于 七层协议模型
不是非常了解的话,你可以,沉下心来看看下面👇🏻 这张图:
那么TCP/IP、UDP
和socket
又有什么关系呢???
Socket
是应用层
与TCP/IP协议族
通信的中间软件抽象层
,它是一组接口
。在设计模式中,Socket
其实就是一个门面模式
,它把复杂的TCP/IP协议族
隐藏在Socket
接口后面,对用户来说,一组简单的接口就是全部,让Socket
去组织数据,以符合指定的协议。
Socket怎么用
这里其实还有很多网络相关的知识需要科普,但是篇幅有限,如果靓仔靓女的你对于这一块有点陌生,你可以买一些网络相关的书籍
《TCP/IP详解 卷1:协议》
《图解HTTP》
《Unix网络编程》
HTTPS权威指南
Socket 作为一套接口,那么是怎么用的呢? 下面一图胜前言: 👇
Socket
传输的特点:
- 1: 传输数据为
字节级
,传输数据可自定义
,数据量小
(对于手机应用讲:费用低) - 2:
传输数据时间短,性能高
- 3: 适合于客户端和服务器端之间信息实时交互
- 4: 可以加密,数据安全性强
正因为这些优势,常被用来做即时通讯重要媒介
上图就是通过 socket
在客户端和终端做的来回通讯
socket使用代码实现:
1: 创建socket
c
int socketID = socket(AF_INET, SOCK_STREAM, 0);
self.clinenId= socketID;
if (socketID == -1) {
NSLog(@"创建socket 失败");
return;
}
domain
:协议域,又称协议族(family)
。常用的协议族有AF_INET
、AF_INET6
、AF_LOCAL
(或称AF_UNIX
,Unix
域Socket
)、AF_ROUTE
等。协议族决定了socket
的地址类型,在通信中必须采用对应的地址,如AF_INET
决定了要用ipv4
地址(32位的)与端口号(16位的)的组合、AF_UNIX
决定了要用一个绝对路径名作为地址。type
:指定Socket类型。常用的socket类型有SOCK_STREAM
、SOCK_DGRAM
、SOCK_RAW
、SOCK_PACKET
、SOCK_SEQPACKET
等。流式Socket
(SOCK_STREAM
)是一种面向连接的Socket
,针对于面向连接的TCP
服务应用。数据报式Socket(SOCK_DGRAM)
是一种无连接的Socket
,对应于无连接的UDP服务应用。protocol
:指定协议。常用协议有IPPROTO_TCP
、IPPROTO_UDP
、IPPROTO_STCP
、IPPROTO_TIPC
等,分别对应TCP
传输协议、UDP传输协议
、STCP
传输协议、TIPC
传输协议。注意:1.
type
和protocol
不可以随意组合,如SOCK_STREAM
不可以跟IPPROTO_UDP
组合。当第三个参数为0
时,会自动选择第二个参数类型对应的默认协议。返回值
:如果调用成功就返回新创建的套接字的描述符,如果失败就返回INVALID_SOCKET
(Linux
下失败返回-1
)
2: 建立连接
```c int result = connect(socketID, (const struct sockaddr *)&socketAddr, sizeof(socketAddr));
if (result != 0) { NSLog(@"链接失败"); return; } NSLog(@"链接成功"); ```
参数一
:套接字描述符参数二
:指向数据结构sockaddr
的指针,其中包括目的端口和IP地址参数三
:参数二sockaddr
的长度,可以通过sizeof(struct sockaddr)
获得返回值
: 成功则返回0
,失败返回非0
,错误码GetLastError()
。
c
struct sockaddr_in socketAddr;
socketAddr.sin_family = AF_INET;
socketAddr.sin_port = SocketPort;
struct in_addr socketIn_addr;
socketIn_addr.s_addr = SocketIP;
socketAddr.sin_addr = socketIn_addr;
__uint8_t sin_len
; 假如没有这个成员,其所占的一个字节被并入到sin_family
成员中sa_family_t sin_family
; 一般来说AF_INET
(地址族)PF_INET
(协议族)in_port_t sin_port
; // 端口struct in_addr sin_addr
; //ip
char sin_zero[8]
; 没有实际意义,只是为了 跟SOCKADDR
结构在内存中对齐
3: 发送消息
c
if (self.sendMsgContent_tf.text.length == 0) {
return;
}
const char *msg = self.sendMsgContent_tf.text.UTF8String;
ssize_t sendLen = send(self.clinenId, msg, strlen(msg), 0);
NSLog(@"发送 %ld 字节",sendLen);
[self showMsg:self.sendMsgContent_tf.text msgType:0];
self.sendMsgContent_tf.text = @"";
* s
:一个用于标识已连接套接口的描述字。
* buf
:包含待发送数据的缓冲区。
* len
:缓冲区中数据的长度。
* flags
:调用执行方式。
* 返回值
: 如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR
.一个中文对应 3 个字节
!UTF8
编码!
4: 接受消息
c
while (1) {
uint8_t buffer[1024];
ssize_t recvLen = recv(self.clinenId, buffer, sizeof(buffer), 0);
if (recvLen == 0) {
NSLog(@"接收到了0个字节");
continue;
}
// buffer -> data -> string
NSData *data = [NSData dataWithBytes:buffer length:recvLen];
NSString *str= [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@---%@",[NSThread currentThread],str);
dispatch_async(dispatch_get_main_queue(), ^{
[self showMsg:str msgType:1];
self.sendMsgContent_tf.text = @"";
});
}
参数一
: 客户端socket
参数二
: 接收内容缓冲区地址参数三
: 接收内容缓存区长度参数四
: 接收方式,0表示阻塞
,必须等待服务器返回数据返回值
:如果成功,则返回读入的字节数,失败则返回SOCKET_ERROR
Socket 总结
Socket
的使用还是非常简单的! 对于iOS开发有点吃力的原因是在于:
* 都是C函数
* 函数参数多并且陌生
* 网络这一块知识的盲区
如果想更加傻瓜式开发,那么就请看下一个篇章:
CocoaAsyncSocket 关于tcp和udp 实战
PS 给大家搞点福利:
【文章第一句】本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
【投稿数量】投稿 ≧4 篇,每篇字数 ≧ 800,即参与成功,可进入奖项评选
【文章内容】非标题党;非面试题整合类文章;技术类文章为佳
【文章分类】前端、后端、iOS、android,选择其他分类无效
【评论抽奖】所有只参与「掘力星计划」活动的文章,文章评论区的用户均可参与评论抽奖。文章作者可以在文中引导用户在评论区进行有质量的互动。
- 引导方式:比如在投稿文章的末尾写「欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边,抽奖详情见活动文章」。
- 抽奖礼物:100份,掘金官方提供,包括掘金徽章、拖鞋、马克杯、帆布袋等,随机发放
- 抽奖时间:「掘力星计划」活动结束后,预计3个工作日内,官方将在所有符合规则的活动文章评论区抽出
- 抽奖方式:掘金官方随机抽奖+人工核实
- 评论内容:与文章内容相关的评论、建议、讨论等,「踩踩」「学习了」等泛泛类的评论无法获奖
评选条件
- 以下奖项评选项:文章质量、文章字数、投稿数量、文章阅读量、互动数据(点赞、评论、收藏)、互动质量(评论是否是与文章内容相关的讨论/建议等)
- 评奖时,运营同学将核对每篇文章,查看是否有刷量等违规行为,如存在违规行为取消已经参与的所有活动的获奖资格
「欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边
,抽奖详情见活动文章」。
我看了,大家如果喜欢掘金的周边的话,大家点点赞还有评论一下,说说你和
socket
那些事~