1、AsyncSocket

  • 基于 CFSocket、GCD 进行的封装(OC)。

  • 支持 TCP 和 UDP。

  • 完整的回调函数(用于处理各种回调事件,连接成功,断开连接,收到数据等)。

  • 需要注意的问题:

    • 1、Socekt 连接成功回调方法中主动调用:[self.socket readDataWithTimeout:-1 tag:0];,相当于主动添加一个读取请求,不然不会执行读取信息回调方法。
    • 2、读取信息回调方法中,读取完信息后,主动调用一下 [self.socket readDataWithTimeout:-1 tag:0];,读取完信息后,重新向队列中添加一个读取请求,不然当收到信息后不会执行读取回调方法。

2、基本使用

2.1 Client 客户端

  • TCP 客户端

    	#import "GCDAsyncSocket.h"
    
    	@interface ViewController () <GCDAsyncSocketDelegate>
    
    	@property (weak, nonatomic) IBOutlet UITextField *addrTF;
    @property (weak, nonatomic) IBOutlet UITextField *portTF; @property (weak, nonatomic) IBOutlet UITextField *msgTF;
    @property (weak, nonatomic) IBOutlet UITextView *logTV; @property (nonatomic, strong) GCDAsyncSocket *clientSockfd; @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad]; // 创建 Socket,在主队列中处理,所有的回执都在主队列中执行。
    self.clientSockfd = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    } - (IBAction)connectBtnClick:(id)sender { NSError *error = nil; // Socket 连接
    if (![self.clientSockfd isConnected]) {
    [self.clientSockfd connectToHost:_addrTF.text onPort:_portTF.text.intValue error:&error];
    } if (error != nil) {
    [self showLogMessage:@"连接失败..."];
    }
    } #pragma mark - GCDAsyncSocketDelegate 协议方法 // 连接成功,协议方法
    - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port { // 读取数据,必须添加,相当于主动添加一个读取请求,不然不会执行读取信息回调方法
    [self.clientSockfd readDataWithTimeout:-1 tag:0]; [self showLogMessage:[NSString stringWithFormat:@"连接服务器地址:%@, 端口:%d 成功", host, port]];
    [self showLogMessage:[NSString stringWithFormat:@"本地地址:%@, 端口:%d", sock.localHost, sock.localPort]];
    } // 已经断开链接,协议方法
    - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { [self showLogMessage:@"socket 断开连接..."];
    } // 读取到数据,协议方法
    - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { // 注意:要想长连接,必须还要在 DidReceiveData 的 delegate 中再写一次 [_udpSocket receiveOnce:&error] // 读取数据,读取完信息后,重新向队列中添加一个读取请求,不然当收到信息后不会执行读取回调方法。
    [self.clientSockfd readDataWithTimeout:-1 tag:0]; NSString *strMsg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    [self showLogMessage:[NSString stringWithFormat:@"recv:%@", strMsg]];
    } #pragma mark - 发送数据 - (IBAction)sendBtnClick:(id)sender { // Socket 发送数据
    [self.clientSockfd writeData:[_msgTF.text dataUsingEncoding:NSUTF8StringEncoding] withTimeout:30 tag:0]; [self showLogMessage:[NSString stringWithFormat:@"send:%@", _msgTF.text]];
    } // 显示信息
    - (void)showLogMessage:(NSString *)msg { _logTV.text = [_logTV.text stringByAppendingFormat:@"%@\n", msg];
    } // 键盘回收
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
    } @end

2.2 Server 服务端

  • TCP 服务端

    	#import <arpa/inet.h>
    #import <ifaddrs.h> #import "GCDAsyncSocket.h" @interface ViewController () <GCDAsyncSocketDelegate> @property (weak, nonatomic) IBOutlet UITextField *addrTF;
    @property (weak, nonatomic) IBOutlet UITextField *portTF; @property (weak, nonatomic) IBOutlet UITextField *msgTF;
    @property (weak, nonatomic) IBOutlet UITextView *logTV; @property (nonatomic, strong) GCDAsyncSocket *serverSocketfd;
    @property (nonatomic, strong) GCDAsyncSocket *clientSocketfd; @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad]; NSString *ip_addr = [self getIPAddress];
    _addrTF.text = ip_addr; // 创建 Socket,在主队列中处理,所有的回执都在主队列中执行。
    self.serverSocketfd = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    } - (IBAction)listenBtnClick:(id)sender { NSError *error = nil; // Socket 监听
    [self.serverSocketfd acceptOnPort:_portTF.text.intValue error:&error]; if (error != nil) {
    NSLog(@"监听出错:%@", error);
    } else{
    [self showLogMessage:@"正在监听..."];
    }
    } #pragma mark - GCDAsyncSocketDelegate 协议方法 // 接收到连接请求,协议方法
    - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket { // 读取数据,必须添加,相当于主动添加一个读取请求,不然不会执行读取信息回调方法
    [newSocket readDataWithTimeout:-1 tag:0]; [self showLogMessage:@"收到客户端连接...."];
    [self showLogMessage:[NSString stringWithFormat:@"客户端地址:%@, 端口:%d", newSocket.connectedHost, newSocket.connectedPort]]; self.clientSocketfd = newSocket;
    } // 已经断开链接,协议方法
    - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { [self showLogMessage:@"socket 断开连接..."];
    } // 读取到数据,协议方法
    - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { // 读取数据,读取完信息后,重新向队列中添加一个读取请求,不然当收到信息后不会执行读取回调方法。
    [sock readDataWithTimeout:-1 tag:0]; NSString *strMsg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    [self showLogMessage:[NSString stringWithFormat:@"recv:%@",strMsg]];
    } #pragma mark - 发送数据 - (IBAction)sendBtnClick:(id)sender { // Socket 发送数据
    [self.clientSocketfd writeData:[_msgTF.text dataUsingEncoding:NSUTF8StringEncoding] withTimeout:30 tag:0]; [self showLogMessage:[NSString stringWithFormat:@"send:%@", _msgTF.text]];
    } #pragma mark - 获取本地 IP 地址 - (NSString *)getIPAddress { NSString *address = @"error";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0; // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces
    temp_addr = interfaces; while (temp_addr != NULL) { if (temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone
    if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String
    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
    }
    }
    temp_addr = temp_addr->ifa_next;
    }
    } // Free memory
    freeifaddrs(interfaces);
    return address;
    } // 显示信息
    - (void)showLogMessage:(NSString *)msg { _logTV.text = [_logTV.text stringByAppendingFormat:@"%@\n", msg];
    } // 键盘回收
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
    } @end

2.3 UDP 通信

  • UDP 通信

    	#import <arpa/inet.h>
    #import <ifaddrs.h> #import "GCDAsyncUdpSocket.h" @interface ViewController () <GCDAsyncUdpSocketDelegate> @property (weak, nonatomic) IBOutlet UITextField *desAddrTF;
    @property (weak, nonatomic) IBOutlet UITextField *desPortTF; @property (weak, nonatomic) IBOutlet UITextField *locAddrTF;
    @property (weak, nonatomic) IBOutlet UITextField *locPortTF; @property (weak, nonatomic) IBOutlet UITextField *msgTF;
    @property (weak, nonatomic) IBOutlet UITextView *logTV; @property (nonatomic, strong) GCDAsyncUdpSocket *udpSocketfd; @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad]; NSString *ip_addr = [self getIPAddress];
    _locAddrTF.text = ip_addr; // 创建 Socket,在主队列中处理,所有的回执都在主队列中执行
    self.udpSocketfd = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    } - (IBAction)connectBtnClick:(id)sender { NSError *error = nil; // 绑定端口
    [self.udpSocketfd bindToPort:_locPortTF.text.intValue error:&error]; if (error != nil) {
    NSLog(@"绑定端口出错:%@", error);
    return;
    } else{
    [self showLogMessage:[NSString stringWithFormat:@"绑定端口 %d 成功...", _locPortTF.text.intValue]];
    } // 开始接收数据
    [self.udpSocketfd beginReceiving:&error]; if (error != nil) {
    NSLog(@"开始接收数据出错:%@", error);
    } else{
    [self showLogMessage:@"开始接收数据..."];
    }
    } #pragma mark - GCDAsyncUdpSocketDelegate 协议方法 // 接收到的数据,协议方法
    - (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
    fromAddress:(NSData *)address
    withFilterContext:(id)filterContext { NSString *strMsg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; [self showLogMessage:[NSString stringWithFormat:@"recv:%@", strMsg]];
    } #pragma mark - 发送数据 - (IBAction)sendBtnClick:(id)sender { // Socket 发送数据
    [self.udpSocketfd sendData:[_msgTF.text dataUsingEncoding:NSUTF8StringEncoding]
    toHost:_desAddrTF.text
    port:_desPortTF.text.intValue
    withTimeout:30 tag:0]; [self showLogMessage:[NSString stringWithFormat:@"send:%@", _msgTF.text]];
    } #pragma mark - 获取本地 IP 地址 - (NSString *)getIPAddress { NSString *address = @"error";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0; // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces
    temp_addr = interfaces; while (temp_addr != NULL) { if (temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone
    if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String
    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
    }
    }
    temp_addr = temp_addr->ifa_next;
    }
    } // Free memory
    freeifaddrs(interfaces);
    return address;
    } // 显示信息
    - (void)showLogMessage:(NSString *)msg { _logTV.text = [_logTV.text stringByAppendingFormat:@"%@\n", msg];
    } // 键盘回收
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
    } @end

2.4 Socket 长连接

  • PublicTool.h

    	@interface PublicTool : NSObject
    
    	// 字典转换成 JSON 字符串
    + (NSString *)JSONStringWithDic:(NSDictionary *)dic; // JSON 字符串转换成字典
    + (NSDictionary *)dictionaryWithJSON:(NSString *)json; @end
  • PublicTool.m

    	@implementation PublicTool
    
    	// 字典转成成 JSON 字符串
    + (NSString *)JSONStringWithDic:(NSDictionary *)dic { NSError *error = nil; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic
    options:0
    error:&error]; if (jsonData == nil) {
    NSLog(@"fail to get JSON from dictionary: %@, error: %@", self, error); return nil;
    }
    NSString *jsonString = [[NSString alloc] initWithData:jsonData
    encoding:NSUTF8StringEncoding]; return jsonString;
    } // JSON 字符串转换成字典
    + (NSDictionary *)dictionaryWithJSON:(NSString *)json { NSError *error = nil; NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData
    options:NSJSONReadingMutableContainers |
    NSJSONReadingAllowFragments
    error:&error]; if (jsonDict == nil) {
    NSLog(@"fail to get dictioanry from JSON: %@, error: %@", json, error); return nil;
    } return jsonDict;
    } @end
  • SocketSingleTon.h

    	@interface SocketSingleTon : NSObject
    
    	@property (nonatomic, copy) NSString *hostAddr;
    @property (nonatomic, copy) NSString *port; @property (nonatomic, copy) void(^msgLog)(NSString *); + (instancetype)shareInstance; // 连接到服务器
    - (void)connectToServer; // 断开连接
    - (void)cutOffSocket; // 发送数据到服务器
    - (void)sendDataToServer:(NSData*)data; @end
  • SocketSingleTon.m

    	#import "GCDAsyncSocket.h"
    #import <netdb.h>
    #import <arpa/inet.h> #import "PublicTool.h" typedef NS_ENUM(NSInteger, SocketOffline) {
    SocketOfflineByServer,
    SocketOfflineByUser
    }; @interface SocketSingleTon () <GCDAsyncSocketDelegate> @property (nonatomic, strong) GCDAsyncSocket *socket; @property (nonatomic, strong) NSTimer *beatTimer; @end @implementation SocketSingleTon + (instancetype)shareInstance { static SocketSingleTon *shareInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    shareInstance = [[self alloc] init];
    });
    return shareInstance;
    } // 连接到服务器
    - (void)connectToServer { NSError *error = nil; if (self.socket != nil) { if ([self.socket isConnected]) { // 断开后再连接
    self.socket.userData = @(SocketOfflineByUser);
    [self cutOffSocket]; [self.socket connectToHost:self.hostAddr onPort:self.port.intValue error:&error]; } else { [self.socket connectToHost:self.hostAddr onPort:self.port.intValue error:&error];
    } } else {
    self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()]; [self.socket connectToHost:self.hostAddr onPort:self.port.intValue error:&error];
    } if (error != nil) {
    NSLog(@"socket 连接失败:%@", error);
    } else {
    NSLog(@"socket 连接成功");
    }
    } // 断开连接
    - (void)cutOffSocket { self.socket.userData = @(SocketOfflineByUser);
    [self.socket disconnect];
    } #pragma mark - GCDAsyncSocketDelegate 协议方法 // 连接成功,协议方法
    - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port { [sock readDataWithTimeout:-1 tag:0]; NSString *logStr = [NSString stringWithFormat:@"连接主机:%@:%d 成功\n", host, port];
    NSLog(@"%@", logStr); if (self.msgLog) {
    self.msgLog(logStr);
    } // 创建定时器,定时发送 beat 包
    self.beatTimer = [NSTimer scheduledTimerWithTimeInterval:5
    target:self
    selector:@selector(longConnectToServer)
    userInfo:nil
    repeats:YES];
    } // 连接断开,协议方法
    - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { self.socket = nil; [self.beatTimer invalidate];
    self.beatTimer = nil; if ([sock.userData isEqual: @(SocketOfflineByUser)]) { NSLog(@"the socket have been cutted off by user"); if (self.msgLog) {
    self.msgLog(@"the socket have been cutted off by user");
    } } else if (sock.userData == SocketOfflineByServer) { NSLog(@"the socket have been cutted off by server"); if (self.msgLog) {
    self.msgLog(@"the socket have been cutted off by server");
    } // reconnect
    [self connectToServer]; } else { NSLog(@"%@", err.localizedDescription); if (self.msgLog) {
    self.msgLog([NSString stringWithFormat:@"%@", err.localizedDescription]);
    } [self connectToServer];
    }
    } // 收到消息,协议方法
    - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { [sock readDataWithTimeout:-1 tag:0]; char buf[1024];
    [data getBytes:buf length:1024]; NSString *receivedData = [NSString stringWithCString:buf encoding:NSUTF8StringEncoding];
    NSLog(@"receivedData:%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); if (receivedData.length > 0) { NSDictionary *dataDic = [PublicTool dictionaryWithJSON:receivedData]; if ([dataDic[@"msgType"] isEqualToString:@"beta"]) {
    NSString *strMsg = [NSString stringWithFormat:@"收到心跳确认的数据:%@\n", receivedData];
    if (self.msgLog) {
    self.msgLog(strMsg);
    }
    } else if ([dataDic[@"msgType"] isEqualToString:@"normal"]) {
    NSString *strMsg = [NSString stringWithFormat:@"收到正常的数据:%@\n", receivedData];
    if (self.msgLog) {
    self.msgLog(strMsg);
    }
    } else if ([dataDic[@"msgType"] isEqualToString:@"exit"]) {
    NSString *strMsg = [NSString stringWithFormat:@"收到关闭的数据:%@\n", receivedData];
    if (self.msgLog) {
    self.msgLog(strMsg);
    }
    [self cutOffSocket];
    }
    }
    } // 发送数据
    - (void)longConnectToServer {
    [self sendDataToServer:[@"hello" dataUsingEncoding:NSUTF8StringEncoding]];
    } // 发送数据到服务器
    - (void)sendDataToServer:(NSData*)data { NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSMutableDictionary *dicParams = [NSMutableDictionary dictionary]; if ([dataStr isEqualToString:@"hello"]) {
    [dicParams setValue:dataStr forKey:@"msg"];
    [dicParams setValue:@"beta" forKey:@"msgType"];
    } else {
    [dicParams setValue:dataStr forKey:@"msg"];
    [dicParams setValue:@"normal" forKey:@"msgType"];
    } NSData *sendData = [[PublicTool JSONStringWithDic:dicParams] dataUsingEncoding:NSUTF8StringEncoding]; NSString *strMsg = [NSString stringWithFormat:@"发送数据: %@\n", [PublicTool JSONStringWithDic:dicParams]];
    if (self.msgLog) {
    self.msgLog(strMsg);
    } [self.socket writeData:sendData withTimeout:30 tag:0];
    } @end
  • ViewController.m

    	#import "SocketSingleTon.h"
    #import "PublicTool.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UITextField *addressTF;
    @property (weak, nonatomic) IBOutlet UITextField *portTF; @property (weak, nonatomic) IBOutlet UITextField *msgTF;
    @property (weak, nonatomic) IBOutlet UITextView *logTV; @end @implementation ViewController - (IBAction)connectToServer:(id)sender { // 创建 Socket
    SocketSingleTon *socketInstance = [SocketSingleTon shareInstance]; socketInstance.hostAddr = _addressTF.text;
    socketInstance.port = _portTF.text; __weak __typeof (self)weakSelf = self;
    socketInstance.msgLog = ^(NSString *log){ dispatch_async(dispatch_get_main_queue(), ^{
    weakSelf.logTV.text = [weakSelf.logTV.text stringByAppendingString:log];
    });
    }; // 连接到服务器
    [socketInstance connectToServer];
    } - (IBAction)cutOffConnect:(id)sender { SocketSingleTon *socketInstance = [SocketSingleTon shareInstance]; // 断开连接
    [socketInstance cutOffSocket];
    } - (IBAction)sendDataToServer:(id)sender { SocketSingleTon *socketInstance = [SocketSingleTon shareInstance]; // 发送数据到服务器
    [socketInstance sendDataToServer:[_msgTF.text dataUsingEncoding:NSUTF8StringEncoding]];
    } - (IBAction)sendBetaDataToServer:(id)sender { SocketSingleTon *socketInstance = [SocketSingleTon shareInstance]; NSMutableDictionary *dicParams = [NSMutableDictionary dictionary];
    [dicParams setValue:@"beta" forKey:@"msgType"];
    [dicParams setValue:@"hello" forKey:@"msg"];
    NSString *strMsg = [PublicTool JSONStringWithDic:dicParams]; // 发送心跳数据到服务器
    [socketInstance sendDataToServer:[strMsg dataUsingEncoding:NSUTF8StringEncoding]];
    } - (IBAction)clearLog:(id)sender {
    _logTV.text = nil;
    } // 键盘回收
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
    } @end

iOS - AsyncSocket 的使用的更多相关文章

  1. IOS AsyncSocket

    导入AsyncSocket.h  AsyncSocket.m   AsyncUdpSocket.h   AsyncUdpSocket.m   以及  CFNetWork.framework async ...

  2. iOS开发之AsyncSocket使用教程

    用socket可以实现像QQ那样发送即时消息的功能.客户端和服务端需要建立长连接,在长连接的情况下,发送消息.客户端可以发送心跳包来检测长连接. 在iOS开发中使用socket,一般都是用第三方库As ...

  3. iOS开发之即时通讯之Socket(AsyncSocket)

    1.AsyncSocket介绍 如果需要在项目中像QQ微信一样做到即时通讯,必须使用socket通讯. iOS中Socket编程的方式: BSD Socket: BSD Socket 是UNIX系统中 ...

  4. iOS学习之Socket使用简明教程- AsyncSocket

    转载自:http://my.oschina.net/joanfen/blog/287238 如果需要在项目中像QQ微信一样做到即时通讯,必须使用socket通讯,本人也是刚学习,分享一下,有什么不对的 ...

  5. IOS使用Asyncsocket进行socket编程

    iphone的标准推荐CFNetwork C库编程.但是编程比较烦躁.在其它OS往往用类来封装的对Socket函数的处理.比如MFC的CAsysncSocket.在iphone也有类似于开源项目.co ...

  6. iOS socket编程 第三方库 AsyncSocket(GCDAsyncSocket)

    Socket描述了一个IP.端口对.它简化了程序员的操作,知道对方的IP以及PORT就可以给对方发送消息,再由服务器端来处理发送的这些消息.所以,Socket一定包含了通信的双发,即客户端(Clien ...

  7. iOS Socket第三方开源类库 ----AsyncSocket

    假如你也是一个java程序员,而你又不是很懂Socket. 下面我的这篇文章也许能帮助你一些. http://xiva.iteye.com/blog/993336 首先我们写好上面文章中的server ...

  8. iOS Socket第三方开源类库 ----AsyncSocket 分类: ios相关 ios技术 2015-03-11 22:14 59人阅读 评论(0) 收藏

    假如你也是一个java程序员,而你又不是很懂Socket. 下面我的这篇文章也许能帮助你一些. http://xiva.iteye.com/blog/993336 首先我们写好上面文章中的server ...

  9. IOS socket编程--Asyncsocket

    iPhone的标准推荐是CFNetwork 库编程,其封装好的开源库是 cocoa AsyncSocket库,用它来简化CFNetwork的调用,它提供了异步操作 主要特性有: 队列的非阻塞的读和写, ...

随机推荐

  1. Java多媒体编程应用

    1. 声音文件的播放 1.1 在Applet中播放声音 在Applet中,可以使用AudioClip来播放声音,它非常简单,只有三个方法:play().loop()和stop(). 例1.1 利用Au ...

  2. Objective-C:MRC手动释放对象内存举例(引用计数器)

    手机内存下的类的设计练习: 设计Book类, 1.三个成员变量:    title(书名)author(作者).price(价格) 2.不使用@property,自己完成存取方法(set方法,get方 ...

  3. OpenCV学习(36) 人脸识别(1)

    本文主要参考OpenCV人脸识别教程:http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html 1.OpenCV ...

  4. OpenCV学习(33) 轮廓的特征矩Moment

    在OpenCV中,可以很方便的计算多边形区域的3阶特征矩,opencv中的矩主要包括以下几种:空间矩,中心矩和中心归一化矩. class Moments { public: ...... // 空间矩 ...

  5. 我所遭遇过的游戏中间件--Apex

    我所遭遇过的游戏中间件--Apex Apex是PhysX的扩展中间件,它是在PhysX的基础上封装了一层.用于实现布料,粒子,破碎这三种物理效果.我只研究其布料处理.使用Apex做物理最大的好处是:它 ...

  6. Informatica 常用组件Lookup之九 配置未连接的查找转换

    在映射中,未连接的查找转换与管道是分开的.您可以使用 :LKP 引用限定符编写表达式以调用其它转换中的查找.未连接查找的常用用法包括: 测试表达式中某个查找的结果 基于查找结果过滤行 基于查找的结果将 ...

  7. 提高你开发效率的十五个 Visual Studio 使用技巧

    相信做开发的没有不重视效率的.开发C#,VB的都知道,我们很依赖VS,或者说,我们很感谢VS.能够对一个IDE产生依赖,说明这个IDE确实 有它的独特之处.无容置疑,VS是一个非常强大的IDE,它支持 ...

  8. Volley框架的介绍使用

    Volley是在2013年的Google I/O 2013大会上发布的,是我们的网络通信更快,更简单,更方便.对于初学者来讲是一个很好的框架. 简单来说,它提供了如下的便利功能: JSON,图像等的异 ...

  9. linux pdb调试总结

    1.首先gdb编译: gcc -g xxx.c -o xxx 2.然后 gdb xxx进入调试 break 行号 加入断点 (1)然后run就能够跑到下一个断点 (2)step(或s)单步跟踪 (3) ...

  10. 几种流行Webservice框架性能对比(转载)

    1摘要 开发webservice应用程序中离不开框架的支持,当open-open网站列举的就有很多种,这对于开发者如何选择带来一定的疑惑.性能Webservice的关键要素,不同的框架性能上存在较大差 ...