1,原文摘自:https://github.com/robbiehanson/CocoaAsyncSocket/wiki/Intro_GCDAsyncSocket
Reading & Writing
One of the best features of the library is "queued read/write operations". What does that mean? A quick code example may explain it best:
NSError *err = nil;
if (![socket connectToHost:@"deusty.com" port:80 error:&err]) // Asynchronous!
{
// If there was an error, it's likely something like "already connected" or "no delegate set"
NSLog(@"I goofed: %@", err);
return;
}
// At this point the socket is NOT connected.
// But I can start writing to it anyway!
// The library will queue all my write operations,
// and after the socket connects, it will automatically start executing my writes!
[socket writeData:request1 withTimeout:-1 tag:1];
// In fact, I know I have 2 requests.
// Why not just get them both out of the way now?
[socket writeData:request2 withTimeout:-1 tag:2];
// Heck, while I'm at it, I might as well queue up the read for the first response.
[socket readDataToLength:responseHeaderLength withTimeout:-1 tag:TAG_RESPONSE_HEADER];
You may have noticed the tag parameter. What's that all about? Well, it's all about convenience for you. The tag parameter you specify is not sent over the socket or read from the socket. The tag parameter is simply echo'd back to you via the various delegate methods. It is designed to help simplify the code in your delegate method.
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
if (tag == 1)
NSLog(@"First request sent");
else if (tag == 2)
NSLog(@"Second request sent");
}
Tags are most helpful when it comes to reading:
#define TAG_WELCOME 10
#define TAG_CAPABILITIES 11
#define TAG_MSG 12
- (void)socket:(AsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag
{
if (tag == TAG_WELCOME)
{
// Ignore welcome message
}
else if (tag == TAG_CAPABILITIES)
{
[self processCapabilities:data];
}
else if (tag == TAG_MSG)
{
[self processMessage:data];
}
}
You see, the TCP protocol is modeled on the concept of a single continuous stream of unlimited length. It's critical to understand this - and is, in fact, the number one cause of confusion that we see.
Imagine that you're trying to send a few messages over the socket. So you do something like this (in pseudocode):
socket.write("Hi Sandy.");
socket.write("Are you busy tonight?");
How does the data show up on the other end? If you think the other end will receive two separate sentences in two separate reads, then you've just fallen victim to a common pitfall! Gasp! But fear not! Your condition isn't life threatening; it's just a common cold. The cure can be found by reading the Common Pitfalls page.
Now that we have that out of the way, you may be wondering about those read methods. Here's a few of them:
- (void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
The first method, readDataToLength, reads and returns data of the given length. Let's take a look at an example:
You're writing the client-side of a protocol where the server sends responses with a fixed-length header. The header for all responses is exactly 8 bytes. The first 4 bytes contain various flags, etc. And the second 4 bytes contain the length of the response data, which is variable. So you might have code that looks like this: