GCDAsyncSocket server receive data only first time
Asked Answered
V

2

6

Client sent message every time when I press send button but Server receive message only first time. What is the issue in server

Server:

- (void)viewDidLoad
{
    [super viewDidLoad];

    asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSError *err = nil;
    if (![asyncSocket acceptOnPort:10000 error:&err]){

        NSLog(@"Error in acceptOnPort:error: -> %@", err);

    }
}

- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
    NSLog(@"Accepted new socket from %@:%hu", [newSocket connectedHost], [newSocket connectedPort]);

    self.asyncSocket = newSocket;
    NSString *welcomMessage = @"Hello from the server\r\n";
    [self.asyncSocket writeData:[welcomMessage dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:1];

    [self.asyncSocket readDataWithTimeout:-1 tag:0];

}

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(@"MSG: %@",msg);

}

Client:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    [socket setDelegate:self];

}

-(IBAction)connectToServer {
    NSError *err = nil;
    if (![socket connectToHost:self.txtIp.text onPort:10000 error:&err]) // Asynchronous!
    {
        // If there was an error, it's likely something like "already connected" or "no delegate set"
        NSLog(@"I goofed: %@", err);
        return;
    }
}

- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"Cool, I'm connected! That was easy.");

     [socket readDataWithTimeout:-1 tag:0];
}

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    if (tag == 1)
        NSLog(@"First request sent");
    else if (tag == 2)
        NSLog(@"Second request sent");
}

- (void)socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag
{
    NSLog(@"Received Data: %@",data);
}


-(void)sendMessage {

    NSData *msg = [self.txtMsg.text dataUsingEncoding:NSUTF8StringEncoding];

    NSLog(@"Data Send: %@",msg);

   [socket writeData:msg withTimeout:-1 tag:1];

}
Vasos answered 11/9, 2014 at 11:15 Comment(4)
Are you receiving message at server for the first time or is it just the call as a result of new socket connection attempt? I believe you are getting the connection call and then client should be getting the welcome message. After that there won't be any reception at server side. Confirm this and i can try to suggest something.Defaulter
@Gandalf: thanks, client getting the welcome message and when client send message only first message can receive server. Other message of client sent success but server can not receive.Vasos
Using your code, but not able to connect to server. Not even at first time. Do you use @"localhost" as parameter?Stillman
@János, see project from github.com/robbiehanson/CocoaAsyncSocketVasos
D
7

You have to make a read call from your server class in didReadData: delegate. Rest is fine. Use below code.

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {

   [sock readDataWithTimeout:-1 tag:0];

    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"MSG: %@",msg);
}
Defaulter answered 12/9, 2014 at 4:44 Comment(0)
N
0

so after struggling with this for a bit, I came up with the following pattern for digesting data. Though the below is an over simplification, it is easily ported to different tasks:

Somewhat Swift Solution 

var dataCache = Data()

func socket(_ sock: GCDAsyncSocket, didConnectToHost host: String, port: UInt16) {
    sock.readData(withTimeout: -1, tag: 0)
}

func socket(_ sock: GCDAsyncSocket, didRead data: Data, withTag tag: Int) {
    dataCache.append(data)
    sock.readData(withTimeout: -1, tag: 0)
}

func socketDidDisconnect(_ sock: GCDAsyncSocket, withError err: Error?) {
    print("Closed with error: \(err)")
    processData()
}

func socketDidCloseReadStream(_ sock: GCDAsyncSocket) {
    print("Closed successfully")
    processData()
}

func processData() {
    // Do something with dataCache eg print it out:
    print("The following read payload:\(String(data:dataCache, encoding: .utf8) ?? "Read data invalid")")
    dataCache = Data()

}
Nullifidian answered 17/1, 2017 at 19:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.