4

我正在尝试使用 cocoaasyncsocket 库附带的 echo 服务器示例的修改版本来执行以下操作:

1) 打开与充当服务器的 python 脚本的连接
2) 发送数据 // 有效,但委托不触发
3) 接收数据 // 委托不触发
4) 断开连接 // 显然不断开连接仍然在我的线程中

目前我在 didFinishLaunchingWithOptions 委托中打开一个连接,然后尝试在 didConnectToHost 委托中发送数据。然后我尝试读取从客户端返回的数据,然后断开连接。

我能够打开连接并发送数据(服务器验证为已接收),但 didWriteDataWithTag 委托永远不会触发。但是,服务器接收数据。然后服务器会返回一些数据,但 didReadData 也不会触发。

除了读/写委托没有触发的事实之外,我组织代码的方式似乎不正确,但我不确定这在事件驱动系统中的外观与运行循环相比如何(I'我是事件驱动的东西+网络的新手)。如果我有一系列动作,其各自的完成是由他们的代表触发的,那么代表是否应该共享某种消息 - 即我们收到“xxx”消息,写回“yyy”?我希望有一个功能来管理所有这些。有这样做的规范方法吗?

IPhoneConnectTestAppDelegate.m(片段)

- (void)localConnect {
    NSError *error = nil;
    if (![asyncSocket connectToHost:@"localhost" onPort:5000 error:&error]) {
        DDLogError(@"Error connecting: %@", error);
    }
}

- (void)disconnect {
    [asyncSocket setDelegate:nil];
    [asyncSocket disconnect];
    [asyncSocket release];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Setup our socket (GCDAsyncSocket).
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];

    [self localConnect];

    // Add the view controller's view to the window and display.
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}


- (void)onSocket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSString *output = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@"didReadData: %@", output);

}

- (void)onSocket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
    NSLog(@"didWriteDataWithTag");
}

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
    NSLog(@"socket:%p didConnectToHost:%@ port:%hu", sock, host, port);
    if(port == 5000)
    {
        NSString *msg = @"q";
        NSData *dataOut = [msg dataUsingEncoding:NSASCIIStringEncoding];
        [asyncSocket writeData:dataOut withTimeout:-1 tag:0];
        [asyncSocket readDataWithTimeout:-1 tag:0];
        [self disconnect];
    }
}

tcpserver.py

# TCP server example
import socket, time
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 5000))
server_socket.listen(5)

print "TCPServer Waiting for client on port 5000"

while 1:
    client_socket, address = server_socket.accept()
    print "I got a connection from ", address
    while 1:
        data = client_socket.recv(512)
        print "Data from client",data

        time.sleep(2)
        data = "xxx"
        print "Sending data to client",data
        client_socket.send (data)
        break;
4

3 回答 3

6

我知道这是一个已经被接受的答案的老问题,但是为了澄清那些发现这个线程正在寻找东西的人,没有调用委托方法的原因是因为 GCDAsynchSocket 以socket:而不是onsocket:ie 开头:

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag

变成:

- (void) socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
于 2012-03-09T21:36:45.643 回答
4

一个朋友的朋友帮我解决了!我们无法让 GCDAsyncSocket 正常工作(连接和写入,但不能读取)。然而,AsyncSocket 在所有 3 个方面都起作用,并且所有代表都正常工作。

#import "AsyncSocket.h"
#import "tcp_clientViewController.h"

@implementation tcp_clientViewController

@synthesize socket;



-(IBAction)connect:(id)sender { 
    NSLog(@"(IBAction)connect");
    NSError *error = nil;
    if (![socket connectToHost:@"localhost" onPort:5000 error:&error]){
        NSLog(@"Error connecting: %@", error);
    }
}

-(IBAction)send:(id)sender {
    NSLog(@"(IBAction)send");


    char bytes[] = "abcd\r\n";
    NSData* data = [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];

    //NSString *msg = @"xxxxx\r\n";
    //NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];


    [socket writeData:data withTimeout:-1 tag:0];
    //NSData *data = [asyncSocket readDataWithTimeout:-1 tag:0];
    [data release];

    [socket readDataToData:[AsyncSocket LFData] withTimeout:-1 tag:0];
}

- (void)viewDidLoad {
    // initialize socket
    socket = [[AsyncSocket alloc] initWithDelegate:self];
}

#pragma mark AsyncSocket Delegate Methods
-(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag {
    NSLog(@"socket:%p didWriteDataWithTag:%@", sock, tag);
}

- (void)socket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag {
    NSLog(@"socket:%p didWritePartialDataOfLength:%@ tag:%@", sock, partialLength, tag);
}

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"socket:%p didConnectToHost:%@ port:%hu", sock, host, port);
}

- (void)socketDidSecure:(AsyncSocket *)sock
{
    NSLog(@"socket:%p socketDidSecure", sock);
}

- (void)socketDidDisconnect:(AsyncSocket *)sock withError:(NSError *)err
{
    NSLog(@"socket:%p socketDidDisconnect withError: %@", sock, err);
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSString* newStr = [NSString stringWithUTF8String:[data bytes]];    
    NSLog(@"socket socketDidReadData:%@", newStr);
}

-(IBAction)disconnect:(id)sender { }

#pragma mark View stuff
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {}

- (void)dealloc {
    self.socket = nil;
    [super dealloc];
}

@end
于 2011-06-22T04:02:39.797 回答
2

尝试使用本地 sock 读取命令并将它们放入写入命令中

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    [sock readDataToData:[AsyncSocket LFData] withTimeout:-1 tag:tag];
}
于 2011-06-17T08:55:50.560 回答