NSOutputStream,NSStreamEventHasSpaceAvailable事件过去后如何正确输出数据?
我将要发送到服务器的消息添加到队列中:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
需要删除 const 并将 strlen 添加到 maxLength。
Needed to remove const and I added strlen to the maxLength.