解决方案 »
- Java中用一个类创建的对象,而不是用基本数据类型创建的数组有什么特点?
- 求一本obj-c书籍
- IN app purchase
- [抓狂]读写文件还是想要用FILE,不习惯NSData,NSFileHandle。。。。。
- 提交APP遇到的问题:11.13: Apps that link to external mechanisms for account creation
- 大哥,如何才能实现瀑布流???跪求demo
- 关于uiscrollview自动出现子控件的奇怪现象
- could not load NIB in bunlde
- IOS 推送DeviceToken
- 自定义Button继承UIControl的问题
- app审核服务器后台问题
- MailCore2怎么编译?
您好,我知道这个要求不好,我刚才这段时间看了下block,应该需要GCD是吗?需要再开线程吗?
我在原来的代码中,将创建 AsyncSocket 的实例 放在主线程,然后创建一个 工作线程 发送数据 我的理解是 跟网络有关的操作应该 放在工作线程,如果是HTTP的话,这样子很容易,因为可以在一个方法里面同时发送并且获取返回的数据,但是在tcp里面,是通过不断监听,来获取数据并且调用 didReadData 方法,我就有点不知所措了,下面是我创建线程调用的错误返回 // 发送登录上行数据
[NSThread detachNewThreadSelector:@selector(writeData:) toTarget:_sock withObject:sendData];
// [_sock writeData:sendData];
NSLog(@"开始发送数据");*** Terminating app due to uncaught exception 'AsyncSocketException', reason: 'Attempting to access AsyncSocket instance from incorrect thread.'
- (void)login
{
// [NSThread detachNewThreadSelector:@selector(loginIn) toTarget:self withObject:nil];
NSLog(@"开始登录:");
// 获取用户输入的 用户名、密码
NSString *username = self.userNameText.text;
NSString *password = self.passwordText.text;
// 获取发送的 16进制 data
NSData *sendData = [ControlProtocol loginWithName:username andPassword:password];
// 获取socket实例
SocketModel *_sock = [SocketModel shareInstance];
// 连接成功,判断用户名密码是否正确
if ([_sock connectServer:HOST_MY_IP port:HOST_MY_PORT] != SRV_CONNECT_FAIL)
{
// 发送登录上行数据
// [NSThread detachNewThreadSelector:@selector(writeData:) toTarget:_sock withObject:sendData];
[_sock writeData:sendData];
NSLog(@"开始发送数据");
}
// 获取下行数据
// NSString *downStr = [NSString stringWithString:_sock.readMsg];
// NSLog(@"down---%@",downStr);
}
在这个代码中,不会出现问题,并且能够正确的发送接收数据,但是 ,必须要等login方法执行完毕,才会调用 didReadData 方法。所以就在login 里面无法获取数据。如果在didReadData里面修改,也是不行的,因为 后面的几个 ViewController 也需要用到 我写的类,最后,我觉得是不是我的思路有问题,如下,我是先包含了类库文件,然后自己新建一个类 SocketModel 采用 AsyncSocketDelegate,这个类中,实例化了一个 共享的全局变量 sock,我想在其他的ViewController 里面 通过[SocketModel shareInstance]的方式获取唯一的实例,然后在每一个 VC 里面通过 唯一的sock 进行 TCP 的数据发送与接受,请问是不是问题出现在了这里?#import <Foundation/Foundation.h>@interface SocketModel : NSObject<AsyncSocketDelegate>@property AsyncSocket *sock;
@property NSData *send;
@property NSData *read;
@property (nonatomic) NSString *readMsg;+ (SocketModel *)shareInstance;// 建立连接,返回连接结果
-(int)connectServer:(NSString *)hostIP port:(int)hostPort;// 发送数据
-(void)writeData:(NSData *)sendData;
@end
在SocketComponent.m(专门负责Socket连接与信息收发的类)中,定义了Block对象,并提供了连接方法:/**
* @brief 连接成功回调Block
*/
typedef void (^block_ConnectSuccess)(NSString *remoteIP,NSInteger remotePort,NSString *localIP,NSInteger localPort);/**
* @brief 连接失败回调Block
*/
typedef void (^block_Connectfailure)(NSError *error);@interface SocketComponent () {
block_ConnectSuccess _connectSuccessBlock; //连接成功回调
block_Connectfailure _connectfailureBlock;
}
- (void)connetServerWithRemoteIP:(NSString *)remoteIP remotePort:(NSInteger)remotePort successCallback:(block_ConnectSuccess)block_Success failureCallback:(block_Connectfailure)block_failure
{
//因为连接成功或失败是异步回调,所以把上层传入Block存起来
_connectSuccessBlock = [block_Success copy];
_connectfailureBlock = [block_failure copy];
}//然后最终在返回密钥时回调成功Block(或返回失败Block)
/**
* @brief 返回密钥的方法
*
* @param moNotification 接收到包含密钥的广播信息实例
*/
- (void)replySecretKey:(MoNotification *)moNotification
{
//成功返回密钥等信息,触发成功回调
if (_connectSuccessBlock) {
_connectSuccessBlock([_asyncSocket connectedHost],[_asyncSocket connectedPort],[_asyncSocket localHost],[_asyncSocket localPort]);
//消除Block
[_connectSuccessBlock release];
_connectSuccessBlock = nil;
[_connectfailureBlock release];
_connectfailureBlock = nil;
}
}
有没有办法 在 login 中 分开做我现在的问题,主要就是,发送过去了数据,如何接收过来,一般情况下 这种 验证登录 的 TCP 都是怎么做的或者说,给 TCP 发送一条数据,然后 接受回来,这个过程怎么实现。我的想法:
1.点击按钮,或者别的什么 触发事件方法
2.在事件方法中 发送一次数据,然后我要拿到服务器返回的数据。(client 和 server 是 一去 一回的 关系);
3.问题:在发送数据的那个方法中,我无法拿到服务器返回的数据,因为,在发送数据的方法执行时,didReadData 方法不会被调用。
4.我想了一下,通过两个方法来实现,先用A发送,发送完之后在 didReadData 中将服务器返回数据 处理。然后点击B按钮,在B 方法中拿到处理后的数据,这个我已经实现了,现在关键就是 如何在同一个方法中去做。