IOS 用封装API AsyncSocket进行网络通信

AsyncSocket是一个用Object-c封装好的网络通讯API,调用方便,容易实现

使用AsyncSocket可以很方便的与其它系统进行Socket通信, AsyncSocket包括TCP和UDP,通过实现委托AsyncSocketDelegate进行交互。

下面是TCP通讯

API 下载地址 :点击下载

首先,调用此API时需先引入CFNetWork.framework

然后在#import "AsyncSocket.h"就可以直接调用了

闲话不多说,上代码:

SocketServer端代码:

.h文件

@interface ViewController :UIViewController<AsyncSocketDelegate,UITextFieldDelegate>
{
    AsyncSocket *listener;//监听客户端请求
    //AsyncUdpSocket *udpSocket;//不需要即时连接就能通讯
    NSMutableArray *connectionSockets;//当前请求连接的客户端
    
    IBOutlet UITextView *ReceiveData;
    IBOutlet UITextField *message;
}

@property (nonatomic, retain)AsyncSocket *listener;
@property (nonatomic, retain)UITextField *message;
@property (nonatomic, retain)UITextView *ReceiveData;


- (IBAction)sendMessage:(id)sender;
- (IBAction)textEndEditting:(id)sender;



.m文件

#import "ViewController.h"
#import "SocketConfig.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize listener;
@synthesize message,ReceiveData;
bool isRunning = NO;//判断当前socket是否已经开始监听socket请求

-(void) sendMessage
{
    if(!isRunning)
    {
        NSError *error = nil;
        if (![listeneracceptOnPort:_SERVER_PORT_error:&error]) {
            return;
        }
        NSLog(@"开始监听");
        isRunning = YES;
    }
    else
    {
        NSLog(@"重新监听");
        [listener disconnect];
        for (int i = 0; i < [connectionSocketscount]; i++) {
            [[connectionSocketsobjectAtIndex:i]disconnect];
        }
        isRunning = FALSE;
    }
}
- (IBAction)sendMessage:(id)sender
{
    if(![message.textisEqual:@""])
    {
        [listener writeData:[message.textdataUsingEncoding:NSUTF8StringEncoding]
                withTimeout:-1 tag:1];
    }
    else
    {
        UIAlertView *alertView =[[UIAlertViewalloc]initWithTitle:@"Waring"message:@"Please Input Message"delegate:nilcancelButtonTitle:@"OK"otherButtonTitles:nil,nil];
        
        [alertView show];
        [alertView release];
    }
}
- (IBAction)textEndEditting:(id)sender
{
    [message resignFirstResponder];
}
- (void)viewDidLoad
{
    ReceiveData.editable=NO;//设置TextView不可以编辑
    listener=[[AsyncSocketalloc]initWithDelegate:self];
    message.delegate=self;
    //初始化连接socket的个数
    connectionSockets=[[NSMutableArrayalloc]initWithCapacity:30];
    [selfsendMessage];
    [superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
{
    [textField resignFirstResponder];
    return YES;
}

#pragma socket委托
//连接socket出错时调用
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
    NSLog(@"%@",[errdescription]);
}
//收到新的socket连接时调用
- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
{
    //将连接服务的客户端记录起来,以便以后实现客户端通信时使用
    [connectionSockets addObject:newSocket];
}
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    [sock readDataWithTimeout: -1tag: 0];
}
//与服务器建立连接时调用(连接成功)
- (void) onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    //这里的host就是当前进行服务器连接的客户端ip
    NSLog(@"host:%@",host);
    NSString *returnMessage=@"Welcome To Socket Test Server!";
    //将NSString转换成为NSData类型
    NSData *data=[returnMessagedataUsingEncoding:NSUTF8StringEncoding];
    //向当前连接服务器的客户端发送连接成功信息
    [sock writeData:data withTimeout:-1tag:0];
}
/**
 * Called when a socket has completed reading the requested data into memory.
 * Not called if there is an error.
 读取客户端发送来的信息(收到socket信息时调用)
 **/
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSString *msg = [[[NSStringalloc]initWithData: dataencoding:NSUTF8StringEncoding]autorelease];
    //获取当前发送消息的客户端ip
    //NSLog(@"%@",sock.connectedHost);
    //NSString *ClientIp=[sock connectedHost];
    NSString *receviceIp=nil;
//从所有连接的客户端当中遍历要接收信息的客户端
    for(int i=0;i<[connectionSocketscount];i++)
    {
        AsyncSocket *s=(AsyncSocket*)[connectionSocketsobjectAtIndex:i];

//这里要说明一下,在想另外一个客户端发送信息时需要指定客户端ip地址,所以在发送消息的时候,应该将ip地址一并写在消息里面,然后由服务端进行处理,我这里这是做了一个简单的Demo,有2个客户端相互发送消息

        if([sock.connectedHostisEqualToString:@"10.0.73.252"])
        {receviceIp=@"10.0.73.251";}
        else
        {receviceIp=@"10.0.73.252";}
        if([s.connectedHostisEqualToString:receviceIp])
        {
            [s writeData:data withTimeout:-1 tag:0];
            if(msg)
            {
                ReceiveData.text = msg;
                NSLog(@"Receive Message:%@",msg);
            }
            else
            {
                NSLog(@"Error converting received data into UTF-8 String");
            }
        }
        else
        {
           //如果遍历不存在,则说明客户端为进行连接
            NSString *returnMes=@"对方不在线!";
            NSData *datareturn=[returnMesdataUsingEncoding:NSUTF8StringEncoding];
            [sock writeData:datareturn withTimeout:-1 tag:0];
        }
    }

}
- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
    [connectionSockets removeObject:sock];
}

#pragma end Deleagte

- (void)didReceiveMemoryWarning
{
    [superdidReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)dealloc
{
    [ReceiveData release],ReceiveData=nil;
    [message release],message=nil;
    [listener release];
    [ReceiveData release];
    [super dealloc];
}
@end






客户端代码:

h文件

#import <UIKit/UIKit.h>
#import "AsyncSocket.h"

@interface ViewController :UIViewController<UITextFieldDelegate>
{
    AsyncSocket *socket;
}
@property (retain, nonatomic) IBOutlet UITextField *clientIPAddress;
@property (retain, nonatomic) IBOutlet UITextView *ReceiveData;
@property (retain, nonatomic) IBOutlet UITextField *SendMessage;
@property (retain, nonatomic) IBOutlet UILabel *Status;

- (IBAction)Send:(id)sender;
- (IBAction)ConnectToSever:(id)sender;
@end




m文件

#import "ViewController.h"
#import "Config.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    _clientIPAddress.delegate=self;
    [_clientIPAddress setTag:1];
    _SendMessage.delegate=self;
    [_SendMessage setTag:2];
    _ReceiveData.editable=NO;
    [superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    if([textField tag]==2)
    {
        [self viewUp];
    }
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
{
    
    [textField resignFirstResponder];
    if([textField tag]==2)
    {
        [self viewDown];
    }
    return YES;
}
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    returnUIInterfaceOrientationPortrait;
}
- (void)didReceiveMemoryWarning
{
    [superdidReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)Send:(id)sender {
    if(![_SendMessage.textisEqualToString:@""] && ![_clientIPAddress.textisEqualToString:@""])
    {
        NSString *message=[NSStringstringWithFormat:@"%@:%@",_clientIPAddress.text,_SendMessage.text];
        if(socket==nil)
        {
            socket=[[AsyncSocketalloc]initWithDelegate:self];
        }
        //NSString *content=[message stringByAppendingString:@"\r\n"];
        [socket writeData:[messagedataUsingEncoding:NSUTF8StringEncoding]withTimeout:-1tag:0];
        _ReceiveData.text=[NSStringstringWithFormat:@"me:%@",_SendMessage.text];
    }
    else
    {
        UIAlertView *alert=[[UIAlertViewalloc]initWithTitle:@"Waring"message:@"Please input Message!"delegate:nilcancelButtonTitle:@"OK"otherButtonTitles:nil,nil];
        [alert show];
        [alert release];
    }
}

- (IBAction)ConnectToSever:(id)sender {
    if(socket==nil)
    {
        socket=[[AsyncSocketalloc]initWithDelegate:self];
        NSError *error=nil;
        if(![socketconnectToHost:_IP_ADDRESS_V4_onPort:_SERVER_PORT_error:&error])
        {
           _Status.text=@"连接服务器失败!";
        }
        else
        {
            _Status.text=@"已连接!";
        }
    }
    else
    {
        _Status.text=@"已连接!";
    }
}

#pragma AsyncScoket Delagate
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
    NSLog(@"onSocket:%p didConnectToHost:%@ port:%hu",sock,host,port);
    [sock readDataWithTimeout:1tag:0];
}
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    [sock readDataWithTimeout: -1tag: 0];
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSString* aStr = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
    self.ReceiveData.text = aStr;
    [aStr release];
    [socket readDataWithTimeout:-1tag:0];
}

- (void)onSocket:(AsyncSocket *)sock didSecure:(BOOL)flag
{
    NSLog(@"onSocket:%p didSecure:YES", sock);
}

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
    NSLog(@"onSocket:%p willDisconnectWithError:%@", sock, err);
}

- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
    //断开连接了
    NSLog(@"onSocketDidDisconnect:%p", sock);
    NSString *msg =@"Sorry this connect is failure";
    _Status.text=msg;
    [msg release];
    socket = nil;
}
- (void) viewUp
{
    CGRect frame=self.view.frame;
    frame.origin.y=frame.origin.y-215;
    [UIView beginAnimations:nilcontext:nil];
    [UIView setAnimationDuration:0.3f];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    self.view.frame=frame;
    [UIView commitAnimations];
}
- (void) viewDown
{
    CGRect frame=self.view.frame;
    frame.origin.y=frame.origin.y+215;
    [UIView beginAnimations:nilcontext:nil];
    [UIView setAnimationDuration:0.3f];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    self.view.frame=frame;
    [UIView commitAnimations];
}
#pragma end Delegate
- (void)dealloc {
    [_ReceiveData release];
    [_SendMessage release];
    [_Status release];
    [_clientIPAddress release];
    [super dealloc];
}



Demo下载地址:客户端下载       服务端下载

微信公众平台已开通,加个关注呗。我们一起学习,一起进步
微信号:ios开发总汇
百度知道群:开发者俱乐部


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值