Question

I add messages I want to send to a server to a queue:

typedef struct StreamOutputQueue{
    char message[513];
    struct StreamOutputQueue * next;
} StreamOutputQueue;

When I get the event NSStreamEventHasSpaceAvailable I send the first message in the queue then remove it so the next message is ready. If the queue if empty I set a flag so I can send the next message straight away without adding it to the queue because the stream is supposed to be ready and the queue is empty.

This is the code after getting the event:

case NSStreamEventHasSpaceAvailable:
            NSLog(@"Space Available!");
            if (login_start) { //Login
                range = [nick_field.text rangeOfString: @" "]; //Find space in nickname text
                if (range.location != NSNotFound) { //Found so include only the text up to the space.
                    used_nick = [nick_field.text substringToIndex: range.location];
                }else{ //Else include it all
                    used_nick = nick_field.text;
                }
                [irc_output_stream write:(const uint8_t *)[[NSString stringWithFormat:@"USER %@ * * :%@ \r\nNICK %@\r\n", used_nick, nick_field.text,used_nick,nil] UTF8String] maxLength:1024]; //Send USER and NICK IRC commands
                login_start = NO; //Login done.
            }else if (output_queue){ //Queue exists
                printf("OUTPUT QUEUE HAS DATA - %s\n",output_queue->message);
                [irc_output_stream write: (const uint8_t *)output_queue->message maxLength:512]; //Send message to server.
                StreamOutputQueue * next = output_queue->next;
                free(output_queue);
                output_queue = next; //Queue pointer points to next node.
                space_available = NO;
            }else{
                space_available = YES; //Nothing sent, space available for immediate data delivery to server. 
            }
            break;

The login works fine. After the login is complete the program starts using the queue to send messages when needed.

Here the the code which adds data to the end of the queue:

- (void) appendToOutputQueue: (char *) message{
    if (space_available) { //Space available with no queue so send the next one now.
        printf("SPACE AVAILABLE NO QUEUE - %s",message);
        [irc_output_stream write: (const uint8_t *)message maxLength:512];
        space_available = NO; //Wait until space is available again
        return; //Do not continue to add to queue
    }
    //Add to queue
    StreamOutputQueue * new;
    new = malloc(sizeof(*new)); //Allocate new node
    new->next = NULL; //Next must be null to signify end
    strcpy(new->message,message); //Copy message data
    if (output_queue) { //If the queue exists add the node to the end
        output_queue_end->next = new;
    }else{ //Else make the queue start at this node
        output_queue = new;
    }
    output_queue_end = new; //The end node is now this one
}

The problem is the server does not recognise the data which is sent though the queue. The data is printed correctly at the printf calls. The login works absolutely fine. It appears to fail each time if the data is sent outside the event method and fails some of the time when it is in the event method where the server will act as if it got corrupted data.

How is this supposed to be done?

Thank you.

Was it helpful?

Solution

Needed to remove const and I added strlen to the maxLength.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top