什么是Socket,XMPP?
Jul 29, 2014
。
网络上的请求就是通过Socket来建立连接然后互相通信
http:192.168.0.1:80/login
(网络上主机设备的唯一标识)
(定位程序)
(用什么样的方式进行交互)
,形成传输数据的通道
(数据大小不收限制)
完成连接,是可靠协议,安全送达
关于三次握手
第一次握手:客户端尝试连接服务器
,向服务器发送syn包(同步序列编号Synchronize Sequence Numbers),syn=j,客户端进入SYN_SEND状态等待服务器确认
第二次握手:服务器接收客户端syn包并确认
(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态
第三次握手:客户端收到服务器的SYN+ACK包
,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手
等场景
UDP是一种无连接的传输层协议,它主要用于不要求分组顺序到达的传输中,分组传输顺序的检查与排序由应用层完成,提供面向事务的简单不可靠信息传送服务。UDP 协议基本上是IP协议与上层协议的接口。UDP协议适用端口分别运行在同一台设备上的多个应用程序。
UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责。
UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP等。
实现Socket的监听方法有:
第三方框,内部是对C的封装
Telnet命令 telnet 192.168.10.10 5288
第三方框,将GCDAsyncSocket的.h和.m文件复制到项目中
#import "ServerSocket.h"
#import "GCDAsyncSocket.h"
@interface ServerSocket ()
/** 服务端Socket */
@property (nonatomic, strong) GCDAsyncSocket *ServerSocket;
/** 存放客户端Socket的数组 */
@property (nonatomic, strong) NSMutableArray *clientSocketArray;
@end
@implementation ServerSocket
/** clientSocketArray的懒加载 */
- (NSMutableArray *)clientSocketArray{
if (!_clientSocketArray) {
_clientSocketArray = [NSMutableArray array];
}
return _clientSocketArray;
}
- (instancetype)init{
if (self = [super init]) {
// 1. 创建服务端Socket对象
self.ServerSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
}
return self;
}
- (void)start{
// 2. 绑定端口,马上监听端口
NSError *error = nil;
[self.ServerSocket acceptOnPort:5288 error:&error];
if (!error) {
NSLog(@"服务端开启成功");
}else{
NSLog(@"服务端开启失败");
}
}
#pragma mark - GCDAsyncSocketDelegate
// 接收到客户端 连接请求
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket{
#warning 将新连接的客户端保存起来,避免断开
[self.clientSocketArray addObject:newSocket];
NSLog(@"连接上的客户端 %ld", self.clientSocketArray.count);
#warning 如果想要接收数据,必须要监听数据的读取
[newSocket readDataWithTimeout:-1 tag:0];
}
// 接收到客户端的数据
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
// 将二进制数据转换为字符串
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", str);
#warning 进行数据读取之前一定要先写这句
[sock readDataWithTimeout:-1 tag:0];
// 把数据发送给其他客户端
for (GCDAsyncSocket *client in self.clientSocketArray) {
if (client != sock) {
[client writeData:data withTimeout:-1 tag:0];
}
}
}
@end
注:iOS项目 会自动开启主运行循环,而 命令行项目 必须手动开启
运行程序,服务端就开始运行了
终端充当客户端,输入以下命令来连接10086服务器:
其中 192.168.10.10
为服务器的IP地址,5288
为服务器端口号
#import "ViewController.h"
#import "GCDAsyncSocket.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputViewBottom;
@property (weak, nonatomic) IBOutlet UIView *inputView;
@property (weak, nonatomic) IBOutlet UIButton *sendButton;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UITextField *textField;
/** 客户端Socket */
@property (nonatomic, strong) GCDAsyncSocket *clientSocket;
/** 存放数据的数组 */
@property (nonatomic, strong) NSMutableArray *dataSource;
@end
@implementation ViewController
static NSString * const cellID = @"cell";
/** dataSource的懒加载 */
- (NSMutableArray *)dataSource{
if (!_dataSource) {
_dataSource = [NSMutableArray array];
}
return _dataSource;
}
- (void)viewDidLoad {
[super viewDidLoad];
// 1. 连接服务器
// 1.1 创建客户端Socket对象
GCDAsyncSocket *clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
// 1.2 连接
NSError *error = nil;
[clientSocket connectToHost:@"192.168.1.102" onPort:5288 error:&error];
if (error) {
NSLog(@"%@", error);
}
self.clientSocket = clientSocket;
// 注册cell
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellID];
}
#pragma mark - GCDAsyncSocketDelegate
// 2. 监听数据读取
/**
* 连接到服务器后调用
*/
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
NSLog(@"与服务器连接成功,建立了通信连接");
#warning 客户端连接成功后,要监听数据读取
[sock readDataWithTimeout:-1 tag:0];
}
/**
* 与服务器断开连接时调用
*/
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
NSLog(@"与服务器断开连接 %@", err);
}
/**
* 接收数据
*/
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@ %@", str, [NSThread currentThread]);
// 准备读取下次的数据
[sock readDataWithTimeout:-1 tag:0];
// -----刷新表格
[self.dataSource addObject:str];
#warning 当前所有的代理都是在子线程调用
// 回到主线程刷新表格
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.tableView reloadData];
}];
}
#pragma mark - Table View Data Source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataSource.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];
cell.textLabel.text = self.dataSource[indexPath.row];
return cell;
}
- (IBAction)sendBtnClick{
// 获取用户输入的文字
NSString *text = self.textField.text;
if (text.length == 0) {
return;
}
// 发送
[self.clientSocket writeData:[text dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
// 刷新表格
[self.dataSource addObject:text];
[self.tableView reloadData];
}
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
NSLog(@"数据发送成功");
}
@end
连接
->传输数据->关闭连接
HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接
。
也可以这样说:短连接是指SOCKET连接后发送后接收完数据后马上断开连接。
连接
->传输数据->保持连接 ->传输数据-> 。。。 ->关闭连接。
长连接指建立Socket连接后不管是否使用都保持连接
,但安全性较差。
关于长连接我们在介绍推送通知
的时候接触过
http1.1- content-type
:multipart/form-data,-
content-length:188,-
body:username=zhangsan&password=123456
传输格式:
zhangsan
lisi
一起吃晚上
XMPP:The Extensible Messaging and Presence Protocol(可扩展通讯和表示协议)
XMPP是一种基于XML的即时通讯协议
,XMPP的官方文档是RFC 3920
XMPP是一个典型的C/S
架构,基本的网络形式是客户端通过TCP/IP连接到服务器,通过Socket建立连接,然后在之上传输XML流
XMPP是一种类似于HTTP协议的一种数据传输协议,其过程就如同“解包装--〉包装”的过程。只需要理解其接收的类型及返回的类型,便可以很好的利用XMPP来进行数据通讯
XMPP官方网站——http://xmpp.org
环信是在XMPP的基础上进行二次开发,将基于移动互联网的即时通讯能力,如单聊、群聊、发语音、发图片、发位置、实时音频、实时视频等,通过云端开放的 Rest API 和客户端 SDK 包的方式提供给开发者和企业。让App内置聊天功能和以前网页中嵌入分享功能一样简单。
SVN使用技巧
Jun 11, 2014
svn checkout :下载服务器的代码到本地 (简写svn co)
svn commit :将改动的文件提交到服务器(简写svn ci)
svn update :更新服务器的代码到本地 (简写svn up)
svn add :向本地的版本控制库中添加新文件
svn delete、svn remove :从本地的版本控制库中删除文件(简写svn del、svn rm)
svn move :移动文件或者目录或文件更名
svn mkdir :创建纳入版本控制下的新目录
svn revert :撤销之前的一切修改
svn merge :将两个版本之间的差异合并到当前文件
svn info :查看文件的详细信息
svn diff :查看不同版本的区别
svn log :查看日志信息
svn list :列出版本库下的文件和目录列表
svn status :查看文件状态(简写svn st)
svn help :获取帮助信息(比如svn help ci)
svn lock :加锁
svn unlock :解锁
第1列状态说明:描述文件被添加、删除或其他修改
--------------------------------------------------------------------------------
' ' 没有修改
'A' 被添加到本地代码仓库
'C' 冲突
'D' 被删除
'I' 被忽略
'M' 被修改
'R' 被替换
'X' 外部定义创建的版本目录
'?' 文件没有被添加到本地版本库内
'!' 文件丢失或者不完整(不是通过svn命令删除的文件)
'~' 受控文件被其他文件阻隔
将项目检出(下载) 至本地
svn checkout URL [PATH]
svn co URL [PATH]
注意:这里的中括号[ ]代表可选(可以省略)
示例
svn checkout https://192.168.1.106/svn/Weibo/ /Users/Documents/workspace
https://192.168.1.106/svn/Weibo/代表的是:代码仓库的远程地址
/Users/Documents/workspace代表的是:将代码下载到本地的哪个路径
如果省略/Users/Documents/workspace的路径,就下载到命令行当前所在的路径
将改动过的文件提交至服务器
svn commit -m "注释" [PATH]
svn ci -m "注释" [PATH]
注意:一定要养成写注释的良好习惯
示例
svn commit -m “修改了User.m文件” /Users/Desktop/workspace/Weibo/branches/User.m
/Users/Desktop/workspace/Weibo/branches/User.m代表的是:提交哪个文件到服务器
如果省略/Users/Desktop/workspace/Weibo/branches/User.m的路径,就将命令行所在路径中所有改动过的文件提交到服务器
提交一个新建的文件到服务器,需要2个步骤
添加新建的文件到本地的版本控制库中:svn add
提交刚才的添加操作到服务器:svn commit
如果直接提交一个没有添加到本地版本控制库中的文件,会报下面的错误
is not a working copy
向本地的版本控制库中添加一个新文件
svn add PATH
示例
svn add /Users/Desktop/workspace/Weibo/branches/User.m
/Users/Desktop/workspace/Weibo/branches/User.m代表的是:添加哪个文件到版本控制库中
删除服务器上的某个文件,需要做2个步骤
将文件从本地的版本控制库中移除:svn delete 、svn remove
提交刚才的删除操作到服务器:svn commit
将文件从本地的版本控制库中移除
svn delete PATH
示例
svn delete /Users/Desktop/workspace/Weibo/branches/User.m
/Users/Desktop/workspace/Weibo/branches/User.m代表的是:将哪个文件从版本控制库中移除
将服务器的最新代码更新到本地
svn update [PATH]
示例
svn update /Users/lnj/Desktop/workspace/Weibo/branches/User.m
/Users/lnj/Desktop/workspace/Weibo/branches/User.m代表的是:更新哪个文件的内容
如果省略/Users/lnj/Desktop/workspace/Weibo/branches/User.m的路径,就更新命令行所在路径的所有内容
将文件恢复至某个版本
svn update -r 版本号 [PATH]
服务端版本回退
svn merge -r 当前版本号:回退版本号 .
.代表更新所有的文件,想更新单个文件可以直接写文件名
(p) postpone 对比(这个比较好)
(mc) mine-conflict 使用我的
(tc) theirs-conflict 使用对方的
svn resolved 文件名 : 解决完冲突后删除生成的临时文件
学习ios 重要还是要理清楚思路 在做或者看老师代码的时候 自己多想想为什么 不要自己看着就抄 另外还是要推荐一下 蓝懿IOS这个培训机构 和刘国斌老师刘国斌老师还是很有名气的,听朋友说刘老师成立了蓝懿iOS,,老师讲课方式很独特,能够尽量让每个人都能弄明白,有的比较难懂的地方,如果有的地方还是不懂得话,老师会换个其它方法再讲解,这对于我们这些学习iOS的同学是非常好的,多种方式的讲解会理解得更全面,这个必须得给个赞,嘻嘻,还有就是这里的学习环境很好,很安静,可以很安心的学习,安静的环境是学习的基础,小班讲课,每个班20几个学生,学习氛围非常好,每天都学到9点多才离开教室,练习的时间很充裕,而且如果在练习的过程中有什么困难,随时可以向老师求助,不像其它机构,通过视频教学,有的甚至学完之后都看不到讲师本人,问点问题都不方便,这就是蓝懿与其它机构的区别,相信在刘国斌老师的细心指导下,每个蓝懿学员都能找到满意的工作,加油!
写博客第一百零七天;
QQ:565803433