NSOutputStream,NSStreamEventHasSpaceAvailable事件过去后如何正确输出数据?

发布于 2024-11-07 10:26:17 字数 2868 浏览 0 评论 0原文

我将要发送到服务器的消息添加到队列中:

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

当我收到事件 NSStreamEventHasSpaceAvailable 时,我发送队列中的第一条消息,然后将其删除,以便下一条消息准备就绪。如果队列为空,我会设置一个标志,这样我就可以立即发送下一条消息,而无需将其添加到队列中,因为流应该已准备好并且队列为空。

这是获取事件后的代码:

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;

登录工作正常。登录完成后,程序开始使用队列在需要时发送消息。

这里是将数据添加到队列末尾的代码:

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

问题是服务器无法识别通过队列发送的数据。数据在 printf 调用时正确打印。登录工作绝对正常。如果数据在事件方法之外发送,则每次都会失败,并且在事件方法中有时会失败,此时服务器将表现得好像收到了损坏的数据。

这应该怎么做?

谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柒夜笙歌凉 2024-11-14 10:26:17

需要删除 const 并将 strlen 添加到 maxLength。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文