4

cocoaasyncsocket ライブラリに付属するエコー サーバーの例の修正版を使用して、次のことを実行しようとしています。

1) サーバーとして機能する Python スクリプトへの接続を開く
2) データを送信する // 機能するが、デリゲートは起動しない
3) データを受信する // デリゲートは起動しない
4) 切断する // 明らかに切断しないまだ私のスレッドに

現在、didFinishLaunchingWithOptions デリゲートで接続を開き、didConnectToHost デリゲートでデータを送信しようとしています。次に、クライアントから返されたデータを読み取ってから切断しようとします。

接続を開いてデータを送信することはできますが (サーバーが受信したことを確認します)、didWriteDataWithTag デリゲートは起動しません。ただし、サーバーはデータを受信します。次に、サーバーはいくつかのデータを起動しますが、didReadData も起動しません。

読み取り/書き込みデリゲートが起動しないという事実に加えて、コードを整理する方法が正しくないようですが、実行ループとは対照的に、イベント駆動型システムでこれがどのように見えるかはわかりません (I'イベント駆動型のもの + ネットワーキングの初心者です)。それぞれの完了がデリゲートによってトリガーされる一連のアクションがある場合、デリゲートは何らかのメッセージを共有する必要がありますか?つまり、「xxx」メッセージを受け取り、「yyy」と書き戻しますか? これらすべてを管理する 1 つの関数が必要です。これを行う標準的な方法はありますか?

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がiesocket:ではなくで始まるためです。onsocket:

- (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

コマンドの読み取りと書き込みコマンドにそれらを配置するためにローカルソックスを使用してみてください

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