Socket编程 --- TCP
TCP socket 原理 :
demo:效果图
Socket编程 --- UDP
本例子使用AsyncSocket 第三方开源库
首先 、导入处理网络数据的库 : ,导入方式如图
1_在.h文件中导入 头文件
#import "AsyncSocket.h"
2_创建两个AsyncSocket类对象,一个作为接收方(服务端)、一个作为发送方(客户端)、和NSMutableArray对象用于接收客户端发送过来的数据。
@interface ViewController : UIViewController{ //服务端 AsyncSocket *recvSocket; // 客户端 AsyncSocket *sendSocket; // NSMutableArray *recvArr; // 判断客户端是否连接到了服务端 BOOL isLink;}
3_界面设置 两个UITextField 一个 UITextView 、一个UIButton 按钮事件,并在xib 中创建相应的控件,相关操作如图所示
@property (retain, nonatomic) IBOutlet UITextField *ipField;@property (retain, nonatomic) IBOutlet UITextField *sendField;@property (retain, nonatomic) IBOutlet UITextView *contentView;- (IBAction)sendText:(id)sender;
二— 切换到 .m 实现文件
1_@synthesize 刚创建的@property 属性
@synthesize ipField;@synthesize sendField;@synthesize contentView;
在 方法中将view 上的对象置为空 。
- (void)viewDidUnload{ // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; [self setIpField:nil]; [self setSendField:nil]; [self setContentView:nil]; [super viewDidUnload]; }
在中将view 上的对象release 掉
- (void)dealloc { [ipField release]; [sendField release]; [contentView release]; [super dealloc];}
1—在 方法中实例化创建的两个AsyncSocket 类对象。和用于接收客户端数据的可变数组
调用 initWithDelegate 初始化,并在.h文件中引入代理
// 记得初始化数组 recvArr = [[NSMutableArray alloc]initWithCapacity:0]; // 服务端 recvSocket = [[AsyncSocket alloc]initWithDelegate:self]; // 客户端 sendSocket = [[AsyncSocket alloc]initWithDelegate:self];
设置服务端(recvSocket)的接收端口号 调用方法 : acceptOnPort:error: (端口号 > 5000 为妙)
// 服务端开始等待别的客户端的链接 // 端口为 > 5000 较合适 : 65535 [recvSocket acceptOnPort:5678 error:nil];
这个时候服务端(recvSocket) 就准备就绪,预留了一条通道让客户端连接并发送数据。首先,客户端必须先取得入口的通行证,才能向服务端发送数据。(客户端发送数据还需经过服务端的许可,只有服务端许可才可以发送数据)。
客户端: 当点击发送的时候就触发连接 、sendSocket 调用 connectToHost:onPort:withTimeout:error:方法连接到服务端。host填的是服务端的ip地址。port 填的是端口(即服务端预留的通道)
当创建连接时,成功连接将调用 onSocket:didConnectToHost:port:方法,证明连接成功
//调用这个方法的时候,就证明链接成功- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{ isLink = YES;}
当连接成功的时候:::::
1——服务端就等待客户端发送数据 调用onSocket:didAcceptNewSocket:
// 调用这个方法证明接受到了一个链接- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket{ //newSocket 就为新的链接 // 客户端和服务器链接 : 将请求保存 (表示同意链接,相当于对newSocket 做了个retain操作) [recvArr addObject:newSocket]; // 等待客户端发送数据 [newSocket readDataWithTimeout:-1 tag:100]; //什么时候读取到了数据}
2——客户端就可以向服务端发送数据了。。。发送的数据要转为NSData格式
客户端(sendSocket)调用writeData:withTimeout:tag: 方法发送数据
- (IBAction)sendText:(id)sender { // 如果没链接,那么去链接服务端 if (sendSocket.isConnected == NO) { // TCP_Socket 的端口当链接过后就释放掉,将不再占用端口 [sendSocket connectToHost:ipField.text onPort:5678 withTimeout:60 error:nil]; //什么时候链接成功 } // NSString -> NSData if (isLink == YES) { NSData *data = [sendField.text dataUsingEncoding:NSUTF8StringEncoding]; // 发送数据 [sendSocket writeData:data withTimeout:60 tag:100]; // 什么时候知道数据发送出去(发送成功) } }
当调用onSocket:didWriteDataWithTag:方法则表示调用数据成功。
// 调用这个方法表示数据发送成功- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag{ if (tag == 100) NSLog(@"yes"); else NSLog(@"no");}
那么服务端什么时候接收到了数据?
onSocket:didReadData:withTag:就表示服务端接收到了用户数据
此时应该继续调用 readDataWithTimeout:tag: 方法一直接收客户端发送过来的数据。
// 调用这个方法就证明接受到了客户端发送的数据- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{ NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; contentView.text = [NSString stringWithFormat:@"%@\n对方说:%@",contentView.text,str]; //继续监听 :(继续等待服务端发送数据) [sock readDataWithTimeout:-1 tag:100]; }
the end !
thx。。