有一段时间没有认真总结和写博客了
前段时间找工作、进入工作阶段。比较少静下来认真总结,现在静下心来总结一下最近的一些心得
前言
AsyncSocket介绍
AsyncSocket详解
AsyncSocket示例
一、前言
公司的项目用到了Socket编程,之前在学习的过程当中,用到的更多的还是http请求的方式。但是既然用到了就必须学习一下,所以就在网上找一些例子,然后想自己写一个demo。可是发现很多写iOS Socket的博客并没有很详细的说明,也可能是大神们觉得其他东西都浅显易懂。
自己专研了一下,将自己的一些理解总结出来,一方面整理自己的学习思路,另一方面,为一些和我有同样困惑的小伙伴们,稍做指引。
二、AsyncSocket介绍
1⃣️iOS中Socket编程的方式有哪些?
-BSD Socket
BSD Socket 是UNIX系统中通用的网络接口,它不仅支持各种不同的网络类型,而且也是一种内部进程之间的通信机制。而iOS系统其实本质就是UNIX,所以可以用,但是比较复杂。
-CFSocket
CFSocket是苹果提供给我们的使用Socket的方式,但是用起来还是会不太顺手。当然想使用的话,可以细细研究一下。
-AsyncSocket
这次博客的主讲内容,也是我们在开发项目中经常会用到的。
2⃣️为什么选择AsyncSocket?
iphone的CFNetwork编程比较艰深。使用AsyncSocket开源库来开发相对较简单,帮助我们封装了很多东西。
三、AsyncSocket详解
1⃣️说明
在我们开发当中,我们主要的任务是开发客户端。所以详解里主要将客户端的整个连接建立过程,以及在说明时候回调哪些函数。在后面的示例代码中,也会给出服务器端的简单开发。
2 过程详解
1.建立连接
- (int)connectServer:(NSString *)hostIP port:(int)hostPort
2.连接成功后,会回调的函数
- (void)onSocket:(AsyncSocket )sock didConnectToHost:(NSString )host port:(UInt16)port
3.发送数据
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
4.接受数据
-(void)onSocket:(AsyncSocket )sock didReadData:(NSData )data withTag:(long)tag
5.断开连接
(void)onSocket:(AsyncSocket )sock willDisconnectWithError:(NSError )err
(void)onSocketDidDisconnect:(AsyncSocket *)sock
主要就是上述的几个方法,只是说在真正开发当中,很可能我们在收发数据的时候,我们收发的数据并不仅仅是一个字符串包装成NSData即可,我们很可能会发送结构体等类型,这个时候我们就需要和服务器端的人员协作来开发:定义怎样的结构体。
四、AsyncSocket示例
客户端代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141#import "ViewController.h"
#define SRV_CONNECTED 0
#define SRV_CONNECT_SUC 1
#define SRV_CONNECT_FAIL 2
#define HOST_IP @"192.168.83.40"
#define HOST_PORT 8008
@interface ViewController ()
{
NSString *_content;
}
-(int) connectServer: (NSString *) hostIP port:(int) hostPort;
-(void)showMessage:(NSString *) msg;
@end
@implementation ViewController
@synthesize clientSocket,tbInputMsg,lblOutputMsg;
#pragma mark - view lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[self connectServer:HOST_IP port:HOST_PORT];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[clientSocket release], clientSocket = nil;
[tbInputMsg release], tbInputMsg = nil;
[lblOutputMsg release], lblOutputMsg = nil;
}
- (int)connectServer:(NSString *)hostIP port:(int)hostPort
{
if (clientSocket == nil)
{
// 在需要联接地方使用connectToHost联接服务器
clientSocket = [[AsyncSocket alloc] initWithDelegate:self];
NSError *err = nil;
if (![clientSocket connectToHost:hostIP onPort:hostPort error:&err])
{
NSLog(@"Error %d:%@", err.code, [err localizedDescription]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[@"Connection failed to host" stringByAppendingString:hostIP] message:[NSString stringWithFormat:@"%d:%@",err.code,err.localizedDescription] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
return SRV_CONNECT_FAIL;
} else {
NSLog(@"Connected!");
return SRV_CONNECT_SUC;
}
}
else {
return SRV_CONNECTED;
}
}
#pragma mark - IBAction
// 发送数据
- (IBAction) sendMsg:(id)sender
{
NSString *inputMsgStr = tbInputMsg.text;
NSString * content = [inputMsgStr stringByAppendingString:@"\r\n"];
NSLog(@"%@",content);
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
// NSData *data = [content dataUsingEncoding:NSISOLatin1StringEncoding];
[clientSocket writeData:data withTimeout:-1 tag:0];
}
// 连接/重新连接
- (IBAction) reconnect:(id)sender
{
int stat = [self connectServer:HOST_IP port:HOST_PORT];
switch (stat) {
case SRV_CONNECT_SUC:
[self showMessage:@"connect success"];
break;
case SRV_CONNECTED:
[self showMessage:@"It's connected,don't agian"];
break;
default:
break;
}
}
- (void)showMessage:(NSString *)msg
{
UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"Alert!"
message:msg
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
- (IBAction)textFieldDoneEditing:(id)sender
{
[tbInputMsg resignFirstResponder];
}
- (IBAction)backgroundTouch:(id)sender
{
[tbInputMsg resignFirstResponder];
}
#pragma mark socket delegate
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
[clientSocket readDataWithTimeout:-1 tag:0];
}
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
NSLog(@"Error");
}
- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
NSString *msg = @"Sorry this connect is failure";
[self showMessage:msg];
[msg release];
clientSocket = nil;
}
- (void)onSocketDidSecure:(AsyncSocket *)sock
{
}
// 接收到数据(可以通过tag区分)
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
_content = lblOutputMsg.text;
NSLog(@"Hava received datas is :%@",aStr);
NSString *newStr = [NSString stringWithFormat:@"\n%@", aStr];
lblOutputMsg.text = [_content stringByAppendingString:newStr];
[aStr release];
[clientSocket readDataWithTimeout:-1 tag:0];
}
@end
服务器端代码
1 | #import "SocketView.h" |
界面搭建