iOS 使用第三方库CocoaAsyncSocket进行Tcp通讯
2016-06-22 02:11
591 查看
iPhone的标准推荐CFNetwork C库编程。但是编程比较烦躁。在其它OS往往用类来封装的对Socket函数的处理。比如MFC的CAsysncSocket.在iphone也有类似于开源项目.cocoa AsyncSocket库, 官方网站: http://code.google.com/p/cocoaasyncsocket/ 它用来简化CFnetwork的调用.。
但是由于中国的长城防火墙,谷歌网站无法访问。因此,这里我是从github上下的 https://github.com/robbiehanson/CocoaAsyncSocket
AsyncSocket分为2个版本(个人理解如下)
(1)GCD版。Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。 简单的说就是基于多线程。
(2)RunLoop版。就是单线程以阻塞处理事件而形成一个消息循环,执行完毕后并不退出。
目录结构如下
AsyncSocket包括TCP和UDP,通过实现委托AsyncSocketDelegate进行交互。
调用此API时需先引入CFNetWork.framework。(网上有的说需要加入该框架,但是为在 iOS9 XCode7beta 中不添加亦可正常运行)
如果是实现GCD版本,则需要将GCD文件夹中的4个文件加入项目
这里只实现GCD版本的Tcp,Udp类似,实现代码如下
1、Main.storyboard
2、ConnectionDef
2、TcpServer.h
3、TcpServer.m
4、TcpClient.h
5、TcpClient.m
7、ViewController.h
8、ViewController.m
实际效果图如下
但是由于中国的长城防火墙,谷歌网站无法访问。因此,这里我是从github上下的 https://github.com/robbiehanson/CocoaAsyncSocket
AsyncSocket分为2个版本(个人理解如下)
(1)GCD版。Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。 简单的说就是基于多线程。
(2)RunLoop版。就是单线程以阻塞处理事件而形成一个消息循环,执行完毕后并不退出。
目录结构如下
AsyncSocket包括TCP和UDP,通过实现委托AsyncSocketDelegate进行交互。
调用此API时需先引入CFNetWork.framework。(网上有的说需要加入该框架,但是为在 iOS9 XCode7beta 中不添加亦可正常运行)
如果是实现GCD版本,则需要将GCD文件夹中的4个文件加入项目
这里只实现GCD版本的Tcp,Udp类似,实现代码如下
1、Main.storyboard
2、ConnectionDef
// // ConnectDef.h // AsyncSocketDemo // // Created by 555chy on 6/22/16. // Copyright © 2016 555chy. All rights reserved. // #ifndef ConnectDef_h #define ConnectDef_h #define DEF_STR_ENCODING NSUTF8StringEncoding //连接超时时间为60秒 #define CONNECT_TIMEOUT 60 #define READ_TIMEOUT -1 //发送数据超时时间为60秒 #define WRITE_TIMEOUT 60 #define SERVER_QUEUE "tcpServerQueue" #define CLIENT_QUEUE "tcpClientQueue" #define SERVER_ADDRESS @"127.0.0.1" #define SERVER_PORT 12345 #endif /* ConnectDef_h */
2、TcpServer.h
// // TcpServer.h // AsyncSocketDemo // // Created by 555chy on 6/21/16. // Copyright © 2016 555chy. All rights reserved. // #import <Foundation/Foundation.h> #import "GCDAsyncSocket.h" #import "ConnectionDef.h" @interface TcpServer : NSObject <GCDAsyncSocketDelegate> { GCDAsyncSocket *serverSocket; NSMutableArray *clientArray; long readTag; long writeTag; } -(long)getReadTag; -(long)getWriteTag; -(void)createTcpSocket:(const char *)queueName acceptOnPort:(uint16_t)port; -(void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket; -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag; -(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag; -(void)socket:(GCDAsyncSocket *)sock writeString:(NSString *)str withTag:(long)tag; -(void)broadcastStr:(NSString *)str; -(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err; @end
3、TcpServer.m
// // TcpServer.m // AsyncSocketDemo // // Created by 555chy on 6/21/16. // Copyright © 2016 555chy. All rights reserved. // #import "TcpServer.h" @implementation TcpServer -(long)getReadTag { return readTag++; } -(long)getWriteTag { return writeTag++; } -(void)createTcpSocket:(const char *)queueName acceptOnPort:(uint16_t)port { clientArray = [NSMutableArray array]; dispatch_queue_t dispatchQueue = dispatch_queue_create(queueName, NULL); serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatchQueue]; [serverSocket acceptOnPort:port error:nil]; readTag = 0; writeTag = 0; } -(void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket { NSString* ip = [newSocket connectedHost]; uint16_t port = [newSocket connectedPort]; NSLog(@"server didAcceptNewSocket [%@:%d]", ip, port); [clientArray addObject:newSocket]; //一直等待readSocket的消息(tag是一个标记类似于tcp数据包中的序列号) [newSocket readDataWithTimeout:READ_TIMEOUT tag:[self getReadTag]]; } -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { NSString *ip = [sock connectedHost]; uint16_t port = [sock connectedPort]; NSString *str = [[NSString alloc] initWithData:data encoding:DEF_STR_ENCODING]; NSLog(@"server didReadData [%@:%d] %@", ip, port, str); //再次接收数据,因为这个方法只接收一次 [sock readDataWithTimeout:READ_TIMEOUT tag:[self getReadTag]]; } -(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag { NSString *ip = [sock connectedHost]; uint16_t port = [sock connectedPort]; NSLog(@"server didWriteDataWithTag [%@:%d]", ip, port); } -(void)socket:(GCDAsyncSocket *)sock writeString:(NSString *)str withTag:(long)tag { NSData *data = [str dataUsingEncoding:DEF_STR_ENCODING]; [sock writeData:data withTimeout:WRITE_TIMEOUT tag:[self getWriteTag]]; } -(void)broadcastStr:(NSString *)str { for(GCDAsyncSocket *sock in clientArray) { [self socket:sock writeString:str withTag:[self getWriteTag]]; } } -(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { NSString *ip = [sock connectedHost]; uint16_t port = [sock connectedPort]; NSLog(@"server socketDidDisconnect [%@:%d]", ip, port); [clientArray removeObject:sock]; } @end
4、TcpClient.h
// // TcpClient.h // AsyncSocketDemo // // Created by 555chy on 6/21/16. // Copyright © 2016 555chy. All rights reserved. // #import <Foundation/Foundation.h> #import "GCDAsyncSocket.h" #import "ConnectionDef.h" @interface TcpClient : NSObject<GCDAsyncSocketDelegate> { GCDAsyncSocket *clientSocket; long readTag; long writeTag; } -(long)getReadTag; -(long)getWriteTag; -(void)createTcpSocket:(const char *)queueName connectToHost:(NSString *) host onPort:(uint16_t)port; -(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port; -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag; -(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag; -(void)writeString:(NSString *)str withTag:(long)tag; -(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err; @end
5、TcpClient.m
// // TcpClient.m // AsyncSocketDemo // // Created by 555chy on 6/21/16. // Copyright © 2016 555chy. All rights reserved. // #import "TcpClient.h" @implementation TcpClient -(long)getReadTag { return readTag++; } -(long)getWriteTag { return writeTag++; } -(void)createTcpSocket:(const char *)queueName connectToHost:(NSString *) host onPort:(uint16_t)port { dispatch_queue_t dispatchQueue = dispatch_queue_create(queueName, NULL); clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatchQueue]; [clientSocket connectToHost:host onPort:port withTimeout:CONNECT_TIMEOUT error:nil]; } -(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port { NSLog(@"client didConnectToHost [%@:%d]", host, port); [sock readDataWithTimeout:READ_TIMEOUT tag:[self getReadTag]]; } -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { NSString *ip = [sock connectedHost]; uint16_t port = [sock connectedPort]; NSString *str = [[NSString alloc] initWithData:data encoding:DEF_STR_ENCODING]; NSLog(@"client didReadData [%@:%d] %@", ip, port, str); } -(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag { NSString *ip = [sock connectedHost]; uint16_t port = [sock connectedPort]; NSLog(@"client didWriteDataWithTag [%@:%d]", ip, port); } -(void)writeString:(NSString *)str withTag:(long)tag { NSData *data = [str dataUsingEncoding:DEF_STR_ENCODING]; [clientSocket writeData:data withTimeout:WRITE_TIMEOUT tag:[self getWriteTag]]; } -(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { NSString *ip = [sock connectedHost]; uint16_t port = [sock connectedPort]; NSLog(@"client socketDidDisconnect [%@:%d]", ip, port); //可以在这边实现断线重连机制 } @end
7、ViewController.h
// // ViewController.h // AsyncSocketDemo // // Created by 555chy on 6/21/16. // Copyright © 2016 555chy. All rights reserved. // #import <UIKit/UIKit.h> #import "TcpServer.h" #import "TcpClient.h" #import "ConnectionDef.h" @interface ViewController : UIViewController @property (nonatomic, retain) TcpServer *tcpServer; @property (nonatomic, retain) TcpClient *tcpClient; @property (weak, nonatomic) IBOutlet UITextField *serverSendTextField; @property (strong, nonatomic) IBOutlet UIView *serverSendButton; @property (weak, nonatomic) IBOutlet UITextField *clientSendTextField; @property (weak, nonatomic) IBOutlet UIButton *clientSendButton; - (IBAction)serverSendButtonClick:(id)sender; - (IBAction)clientSendButtonClick:(id)sender; @end
8、ViewController.m
// // ViewController.m // AsyncSocketDemo // // Created by 555chy on 6/21/16. // Copyright © 2016 555chy. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _tcpServer = [[TcpServer alloc] init]; _tcpClient = [[TcpClient alloc] init]; [_tcpServer createTcpSocket:SERVER_QUEUE acceptOnPort:SERVER_PORT]; [_tcpClient createTcpSocket:CLIENT_QUEUE connectToHost:SERVER_ADDRESS onPort:SERVER_PORT]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)serverSendButtonClick:(id)sender { [_tcpServer broadcastStr:_serverSendTextField.text]; } - (IBAction)clientSendButtonClick:(id)sender { [_tcpClient writeString:_clientSendTextField.text withTag:[_tcpClient getWriteTag]]; } @end
实际效果图如下
相关文章推荐
- LAMP——httpd 2.4.20 + mysql-5.6.26 + php-5.6.22编译安装过程
- win10 导航已取消 解决 亲身验证 !
- raspberry pi 3网络网卡信息
- Http 协议 & HttpURLConnection
- 网络购物分析-java
- nginx1.6.2+tomcat8.0.36 配置https
- 12-227 网络客户端开发(TCP)
- scapyd scrapyd-client scrapy使用http调度spider.md
- AngularJs练习Demo9 Http
- 利用FastJson来解析网络数据
- HTTP协议/RTSP协议/RTMP协议的区别
- HTTP与HTTPS的区别
- tcp总结
- linux网络编程-----实现并发访问网站------
- 使用HOG特征+BP神经网络进行车标识别
- 网络编程常见类型定义
- TCP/IP协议
- 【网络编程5】Java与Python套接字Socket通信的例子
- C#检测本地网络状态
- 详解https是如何确保安全的?