• iPhone的Socket编程使用开源代码之AsyncSocket


    假如你也是一个java程序员,而你又不是很懂Socket。

    下面我的这篇文章也许能帮助你一些。

    http://xiva.iteye.com/blog/993336

     

    首先我们写好上面文章中的server端。

    下面我们可以访问一下下面的地址:

     

    http://code.google.com/p/cocoaasyncsocket/

    这是一个开源框架。呵,不知道拿到自己程序中使用是否涉及侵权。

    但是这句话“The CocoaAsyncSocket project is in the public domain.”是我有信心使用它们的源码,否则只能自己用c来写了,或者使用CFSocket、CFNetwork等类自己来写了。不过也无妨,应在在使用线程的情况下,我们也是可以实现的。

     

    总之,为了开发的便捷,我使用了AsyncSocket这个类,这样可以异步通信。

     

    建立一个基于视图的应用程序,按照http://code.google.com/p/cocoaasyncsocket/wiki/Reference_AsyncSocket

    我们AsyncSocket.h和AsyncSocket.m到我们的项目中,并且导入CFNetwork.framework。这样基本准备工作就做好了。

    下面提供我的应用中的代码以及界面图:

    Socketdemoviewcontroller.h代码 复制代码 收藏代码
    1. //   
    2. //  SocketDemoViewController.h   
    3. //  SocketDemo   
    4. //   
    5. //  Created by xiang xiva on 10-7-10.   
    6. //  Copyright 2010 __MyCompanyName__. All rights reserved.   
    7. //   
    8.   
    9. #import <UIKit/UIKit.h>   
    10. #import "AsyncSocket.h"  
    11. #define SRV_CONNECTED 0  
    12. #define SRV_CONNECT_SUC 1  
    13. #define SRV_CONNECT_FAIL 2  
    14. #define HOST_IP @"192.168.110.1"  
    15. #define HOST_PORT 8080  
    16.   
    17. @interface SocketDemoViewController : UIViewController {   
    18.        
    19.     UITextField *inputMsg;   
    20.     UILabel *outputMsg;   
    21.     AsyncSocket *client;   
    22. }   
    23.   
    24. @property (nonatomic, retain) AsyncSocket *client;   
    25. @property (nonatomic, retain) IBOutlet UITextField *inputMsg;   
    26. @property (nonatomic, retain) IBOutlet UILabel *outputMsg;   
    27.   
    28. - (int) connectServer: (NSString *) hostIP port:(int) hostPort;   
    29. - (void) showMessage:(NSString *) msg;   
    30. - (IBAction) sendMsg;   
    31. - (IBAction) reConnect;   
    32. - (IBAction) textFieldDoneEditing:(id)sender;   
    33. - (IBAction) backgroundTouch:(id)sender;   
    34.   
    35. @end  
    //
    //  SocketDemoViewController.h
    //  SocketDemo
    //
    //  Created by xiang xiva on 10-7-10.
    //  Copyright 2010 __MyCompanyName__. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    #import "AsyncSocket.h"
    #define SRV_CONNECTED 0
    #define SRV_CONNECT_SUC 1
    #define SRV_CONNECT_FAIL 2
    #define HOST_IP @"192.168.110.1"
    #define HOST_PORT 8080
    
    @interface SocketDemoViewController : UIViewController {
    	
    	UITextField *inputMsg;
    	UILabel *outputMsg;
    	AsyncSocket *client;
    }
    
    @property (nonatomic, retain) AsyncSocket *client;
    @property (nonatomic, retain) IBOutlet UITextField *inputMsg;
    @property (nonatomic, retain) IBOutlet UILabel *outputMsg;
    
    - (int) connectServer: (NSString *) hostIP port:(int) hostPort;
    - (void) showMessage:(NSString *) msg;
    - (IBAction) sendMsg;
    - (IBAction) reConnect;
    - (IBAction) textFieldDoneEditing:(id)sender;
    - (IBAction) backgroundTouch:(id)sender;
    
    @end
    
     
    socketdemoviewcontroller.m代码 复制代码 收藏代码
    1. //   
    2. //  SocketDemoViewController.m   
    3. //  SocketDemo   
    4. //   
    5. //  Created by xiang xiva on 10-7-10.   
    6. //  Copyright 2010 __MyCompanyName__. All rights reserved.   
    7. //   
    8.   
    9. #import "SocketDemoViewController.h"  
    10.   
    11. @implementation SocketDemoViewController   
    12.   
    13. @synthesize inputMsg, outputMsg;   
    14. @synthesize client;   
    15. /*   
    16. // The designated initializer. Override to perform setup that is required before the view is loaded.   
    17. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {   
    18.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];   
    19.     if (self) {   
    20.         // Custom initialization   
    21.     }   
    22.     return self;   
    23. }   
    24. */   
    25.   
    26. /*   
    27. // Implement loadView to create a view hierarchy programmatically, without using a nib.   
    28. - (void)loadView {   
    29. }   
    30. */   
    31.   
    32.   
    33.   
    34. // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.   
    35. - (void)viewDidLoad {   
    36.     //[super viewDidLoad];   
    37.     [self connectServer:HOST_IP port:HOST_PORT];   
    38.     //监听读取   
    39.        
    40. }   
    41.   
    42.   
    43.   
    44. // Override to allow orientations other than the default portrait orientation.   
    45. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {   
    46.     return YES;   
    47. }   
    48.   
    49. - (void)didReceiveMemoryWarning {   
    50.     // Releases the view if it doesn't have a superview.   
    51.     [super didReceiveMemoryWarning];   
    52.        
    53.     // Release any cached data, images, etc that aren't in use.   
    54. }   
    55.   
    56. - (void)viewDidUnload {   
    57.     self.client = nil;   
    58.     // Release any retained subviews of the main view.   
    59.     // e.g. self.myOutlet = nil;   
    60. }   
    61.   
    62. - (int) connectServer: (NSString *) hostIP port:(int) hostPort{   
    63.        
    64.     if (client == nil) {   
    65.         client = [[AsyncSocket alloc] initWithDelegate:self];   
    66.         NSError *err = nil;   
    67.         //192.168.110.128  
    68.         if (![client connectToHost:hostIP onPort:hostPort error:&err]) {   
    69.             NSLog(@"%@ %@", [err code], [err localizedDescription]);   
    70.                
    71.             UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[@"Connection failed to host "    
    72.                                             stringByAppendingString:hostIP]    
    73.                                                             message:[[[NSString alloc]initWithFormat:@"%@",[err code]] stringByAppendingString:[err localizedDescription]]    
    74.                                                            delegate:self    
    75.                                                   cancelButtonTitle:@"OK"  
    76.                                                   otherButtonTitles:nil];   
    77.             [alert show];   
    78.             [alert release];   
    79.             //client = nil;   
    80.             return SRV_CONNECT_FAIL;   
    81.         } else {   
    82.             NSLog(@"Conectou!");   
    83.             return SRV_CONNECT_SUC;   
    84.         }   
    85.     }   
    86.     else {   
    87.         [client readDataWithTimeout:-1 tag:0];   
    88.         return SRV_CONNECTED;   
    89.     }   
    90.        
    91. }   
    92.   
    93. - (IBAction) reConnect{   
    94.     int stat = [self connectServer:HOST_IP port:HOST_PORT];   
    95.     switch (stat) {   
    96.         case SRV_CONNECT_SUC:   
    97.             [self showMessage:@"connect success"];   
    98.             break;   
    99.         case SRV_CONNECTED:   
    100.             [self showMessage:@"It's connected,don't agian"];   
    101.             break;   
    102.         default:   
    103.             break;   
    104.     }   
    105. }   
    106.   
    107. - (IBAction) sendMsg{   
    108.        
    109.     NSString *inputMsgStr = self.inputMsg.text;   
    110.     NSString * content = [inputMsgStr stringByAppendingString:@"\r\n"];   
    111.     NSLog(@"%a",content);   
    112.     NSData *data = [content dataUsingEncoding:NSISOLatin1StringEncoding];   
    113.     [client writeData:data withTimeout:-1 tag:0];   
    114.        
    115.     //[data release];   
    116.     //[content release];   
    117.     //[inputMsgStr release];   
    118.     //继续监听读取   
    119.     //[client readDataWithTimeout:-1 tag:0];   
    120. }   
    121.   
    122. #pragma mark -   
    123. #pragma mark close Keyboard   
    124. - (IBAction) textFieldDoneEditing:(id)sender{   
    125.     [sender resignFirstResponder];   
    126. }   
    127.   
    128. - (IBAction) backgroundTouch:(id)sender{   
    129.     [inputMsg resignFirstResponder];   
    130. }   
    131.   
    132. #pragma mark socket uitl   
    133.   
    134. - (void) showMessage:(NSString *) msg{   
    135.     UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"Alert!"  
    136.                                                     message:msg   
    137.                                                    delegate:nil   
    138.                                           cancelButtonTitle:@"OK"  
    139.                                           otherButtonTitles:nil];   
    140.     [alert show];   
    141.     [alert release];   
    142. }   
    143.   
    144.   
    145. #pragma mark socket delegate   
    146.   
    147. - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{   
    148.     [client readDataWithTimeout:-1 tag:0];   
    149. }   
    150.   
    151. - (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err   
    152. {   
    153.     NSLog(@"Error");   
    154. }   
    155.   
    156. - (void)onSocketDidDisconnect:(AsyncSocket *)sock   
    157. {   
    158.     NSString *msg = @"Sorry this connect is failure";   
    159.     [self showMessage:msg];   
    160.     [msg release];   
    161.     client = nil;   
    162. }   
    163.   
    164. - (void)onSocketDidSecure:(AsyncSocket *)sock{   
    165.        
    166. }   
    167.   
    168. - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{   
    169.        
    170.     NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];   
    171.     NSLog(@"Hava received datas is :%@",aStr);   
    172.     self.outputMsg.text = aStr;   
    173.     [aStr release];   
    174.     [client readDataWithTimeout:-1 tag:0];   
    175. }   
    176.   
    177. #pragma mark dealloc   
    178.   
    179. - (void)dealloc {   
    180.        
    181.     [client release];   
    182.     [inputMsg release];   
    183.     [outputMsg release];   
    184.     [super dealloc];   
    185. }   
    186.   
    187. @end  
    //
    //  SocketDemoViewController.m
    //  SocketDemo
    //
    //  Created by xiang xiva on 10-7-10.
    //  Copyright 2010 __MyCompanyName__. All rights reserved.
    //
    
    #import "SocketDemoViewController.h"
    
    @implementation SocketDemoViewController
    
    @synthesize inputMsg, outputMsg;
    @synthesize client;
    /*
    // The designated initializer. Override to perform setup that is required before the view is loaded.
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    */
    
    /*
    // Implement loadView to create a view hierarchy programmatically, without using a nib.
    - (void)loadView {
    }
    */
    
    
    
    // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
    - (void)viewDidLoad {
        //[super viewDidLoad];
    	[self connectServer:HOST_IP port:HOST_PORT];
    	//监听读取
    	
    }
    
    
    
    // Override to allow orientations other than the default portrait orientation.
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        return YES;
    }
    
    - (void)didReceiveMemoryWarning {
    	// Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
    	
    	// Release any cached data, images, etc that aren't in use.
    }
    
    - (void)viewDidUnload {
    	self.client = nil;
    	// Release any retained subviews of the main view.
    	// e.g. self.myOutlet = nil;
    }
    
    - (int) connectServer: (NSString *) hostIP port:(int) hostPort{
    	
    	if (client == nil) {
    		client = [[AsyncSocket alloc] initWithDelegate:self];
    		NSError *err = nil;
    		//192.168.110.128
    		if (![client connectToHost:hostIP onPort:hostPort error:&err]) {
    			NSLog(@"%@ %@", [err code], [err localizedDescription]);
    			
    			UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[@"Connection failed to host " 
    											stringByAppendingString:hostIP] 
    															message:[[[NSString alloc]initWithFormat:@"%@",[err code]] stringByAppendingString:[err localizedDescription]] 
    														   delegate:self 
    												  cancelButtonTitle:@"OK"
    												  otherButtonTitles:nil];
    			[alert show];
    			[alert release];
    			//client = nil;
    			return SRV_CONNECT_FAIL;
    		} else {
    			NSLog(@"Conectou!");
    			return SRV_CONNECT_SUC;
    		}
    	}
    	else {
    		[client readDataWithTimeout:-1 tag:0];
    		return SRV_CONNECTED;
    	}
    	
    }
    
    - (IBAction) reConnect{
    	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;
    	}
    }
    
    - (IBAction) sendMsg{
    	
    	NSString *inputMsgStr = self.inputMsg.text;
    	NSString * content = [inputMsgStr stringByAppendingString:@"\r\n"];
    	NSLog(@"%a",content);
    	NSData *data = [content dataUsingEncoding:NSISOLatin1StringEncoding];
    	[client writeData:data withTimeout:-1 tag:0];
    	
    	//[data release];
    	//[content release];
    	//[inputMsgStr release];
    	//继续监听读取
    	//[client readDataWithTimeout:-1 tag:0];
    }
    
    #pragma mark -
    #pragma mark close Keyboard
    - (IBAction) textFieldDoneEditing:(id)sender{
    	[sender resignFirstResponder];
    }
    
    - (IBAction) backgroundTouch:(id)sender{
    	[inputMsg resignFirstResponder];
    }
    
    #pragma mark socket uitl
    
    - (void) showMessage:(NSString *) msg{
    	UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"Alert!"
                                                        message:msg
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
    
    
    #pragma mark socket delegate
    
    - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{
    	[client 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];
    	client = nil;
    }
    
    - (void)onSocketDidSecure:(AsyncSocket *)sock{
    	
    }
    
    - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    	
    	NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    	NSLog(@"Hava received datas is :%@",aStr);
    	self.outputMsg.text = aStr;
    	[aStr release];
    	[client readDataWithTimeout:-1 tag:0];
    }
    
    #pragma mark dealloc
    
    - (void)dealloc {
    	
    	[client release];
    	[inputMsg release];
    	[outputMsg release];
        [super dealloc];
    }
    
    @end
    

    还是先给出我的界面吧,否则很难懂这些代码

    iPad界面

     

     

    这样大家满意了吧!

     

    好了说了这么多我们还是来看看代码究竟怎么回事吧。

    首先从头文件开始看吧,

    1,导入头文件#import "AsyncSocket.h",然后是一些宏

    2,声明一个AsyncSocket对象,其他就是一些IBoutlet

    再次我们看看视图加载,

     

     

    Java代码 复制代码 收藏代码
    1. - (void)viewDidLoad {   
    2.     //[super viewDidLoad];   
    3.     [self connectServer:HOST_IP port:HOST_PORT];   
    4.     //监听读取   
    5.        
    6. }  
    - (void)viewDidLoad {
        //[super viewDidLoad];
    	[self connectServer:HOST_IP port:HOST_PORT];
    	//监听读取
    	
    }

     显然我们调用了connectServer::这个方法。

    在这个方法中,首先初始化我们的对象,使用代理的方式。对象显示是self。然后我们便需在我们的类中实现它的各种方法,来得到各种我们想得到的。

    client = [[AsyncSocket alloc] initWithDelegate:self];

     

    下面就是连接服务器了,

    [client connectToHost:hostIP onPort:hostPort error:&err]

     

    并且当client不为空时,我们就读取服务器的信息

    [client readDataWithTimeout:-1 tag:0];

     

     

     

    Java代码 复制代码 收藏代码
    1. - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{   
    2.        
    3.     NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];   
    4.     NSLog(@"Hava received datas is :%@",aStr);   
    5.     self.outputMsg.text = aStr;   
    6.     [aStr release];   
    7.     [client readDataWithTimeout:-1 tag:0];   
    8. }  
    - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    	
    	NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    	NSLog(@"Hava received datas is :%@",aStr);
    	self.outputMsg.text = aStr;
    	[aStr release];
    	[client readDataWithTimeout:-1 tag:0];
    }
     

     

    在这个方法中很耐人寻味,主要就是在于递归的调用。

     

     

    Sendmsg代码 复制代码 收藏代码
    1. - (IBAction) sendMsg{   
    2.        
    3.     NSString *inputMsgStr = self.inputMsg.text;   
    4.     NSString * content = [inputMsgStr stringByAppendingString:@"\r\n"];   
    5.     NSLog(@"%a",content);   
    6.     NSData *data = [content dataUsingEncoding:NSISOLatin1StringEncoding];   
    7.     [client writeData:data withTimeout:-1 tag:0];   
    8. }  
    - (IBAction) sendMsg{
    	
    	NSString *inputMsgStr = self.inputMsg.text;
    	NSString * content = [inputMsgStr stringByAppendingString:@"\r\n"];
    	NSLog(@"%a",content);
    	NSData *data = [content dataUsingEncoding:NSISOLatin1StringEncoding];
    	[client writeData:data withTimeout:-1 tag:0];
    }

     我们在看看上面发送消息的代码,中的在于"\r\n"的拼接,否则在java端的程序,无法知道你发过来的信息是否结束,当然你也可以使用其他的方式来读取客户端,比如定时;但是我在java端写的server是readLine来判断的,所以需要拼接这个\r\n.

     

     

    其他的代码除了asyncSocket代理外都是我们所熟悉的。

     

    这些都是asyncsocket代理的代码 复制代码 收藏代码
    1. - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{   
    2.     [client readDataWithTimeout:-1 tag:0];   
    3. }   
    4.   
    5. - (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err   
    6. {   
    7.     NSLog(@"Error");   
    8. }   
    9.   
    10. - (void)onSocketDidDisconnect:(AsyncSocket *)sock   
    11. {   
    12.     NSString *msg = @"Sorry this connect is failure";   
    13.     [self showMessage:msg];   
    14.     [msg release];   
    15.     client = nil;   
    16. }   
    17.   
    18. - (void)onSocketDidSecure:(AsyncSocket *)sock{   
    19.        
    20. }   
    21.   
    22. - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{   
    23.        
    24.     NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];   
    25.     NSLog(@"Hava received datas is :%@",aStr);   
    26.     self.outputMsg.text = aStr;   
    27.     [aStr release];   
    28.     [client readDataWithTimeout:-1 tag:0];   
    29. }  
    - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{
    	[client 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];
    	client = nil;
    }
    
    - (void)onSocketDidSecure:(AsyncSocket *)sock{
    	
    }
    
    - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    	
    	NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    	NSLog(@"Hava received datas is :%@",aStr);
    	self.outputMsg.text = aStr;
    	[aStr release];
    	[client readDataWithTimeout:-1 tag:0];
    }
    
     

    到此就结束了。

     

    其他要说的,明天再完善吧。

     

  • 相关阅读:
    mysql 系统表的作用
    从事务隔离级别谈到Hibernate乐观锁,悲观锁
    python 模拟登陆,请求包含cookie信息
    Python入门介绍
    mysql中设置小数
    分割png图片
    ubuntu 14.04 安装win7虚拟机
    rwx
    获取文件名称 basename 用法
    like tp
  • 原文地址:https://www.cnblogs.com/zhwl/p/2837619.html
Copyright © 2020-2023  润新知