iPhone的Socket编程使用开源代码之AsyncSocket(转)

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

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

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

来自:http://www.iteye.com/topic/993392 

首先我们写好上面文章中的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<系统包>。这样基本准备工作就做好了。

添加 CFNetwork.framework的位置:"/System/Library/Frameworks/CFNetwork.framework,如果没有则

/Developer/Platforms/iphoneOS.platform/Developer/SDKs/iphoneOS4.3.sdk/System/Library/Frameworks文件夹下

iphoneOS4.3.sdk根据你的版本的不同而不同

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

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.m代码

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

 

 

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

 

这样大家满意了吧!

 

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

首先从头文件开始看吧,

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 }

 显然我们调用了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 }

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

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 }

 我们在看看上面发送消息的代码,中的在于"\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 }

 

到此就结束了。

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

posted @ 2012-06-08 11:10  cpcpc  阅读(2055)  评论(0编辑  收藏  举报