Re: Socket Blocking Question
Re: Socket Blocking Question
- Subject: Re: Socket Blocking Question
- From: "Carter R. Harrison" <email@hidden>
- Date: Wed, 20 Jan 2010 14:42:12 -0500
On Jan 20, 2010, at 2:23 PM, Ken Thomases wrote:
> On Jan 20, 2010, at 11:39 AM, Carter R. Harrison wrote:
>
>> I need some folks experienced with cocoa and socket programming to weigh in for me on some design problems I've been having. I'm designing an application that acts as a client in a client-server model. The client communicates with the server over the network by issuing a request and then receiving a response. Requests can only be issued one at a time, meaning that a request cannot be sent until a response from any outstanding request is first received. My application works in such a way that the it could request a handle to an object on the server and then use that handle in subsequent requests to retrieve additional information about the object. I see two ways of modeling the application - I've tried both and I'm not particularly happy with either.
>>
>> The first is to send a request, and then have the socket block until a response is received. This benefit to this model is that it is so much easier to write the higher level application code. The issue with this model is that over a slow network connection it can take a considerable amount of time for the response to come back from the server and while that is happening my CPU usage is through the roof b/c the thread is blocking.
>
> If you're using lots of CPU time, then you're not blocking, you're spinning. When a thread is blocked, it does nothing and consumes no CPU time.
>
> Now, blocking is bad in the main thread of a GUI app, but if you're writing non-GUI code, it can be a perfectly sensible design approach. However, you have to actually implement blocking!
Ken - thanks for the info. I had thought the same thing when I wrote the code so I must be doing something wrong as you said. Here's my method that sends data and then waits for the response back from the server. I've paired my code down so it is a bit simpler than it actually is, but the gist of it is the same. Here the request is sent to the server and the method does not return until 1024 bytes of data has been returned. I'm basically calling [NSInputStream hasBytesAvailable] and if it returns NO then I am using the sleep() method to sleep the thread for 100ms. Over a fast connection the CPU usage is very very low (< 2%), but on a slower connection where the server could take a couple hundred milliseconds to return the CPU usage hovers around 25 or 30% - way too high for regular use. In the code, "is" is an NSInputStream and "os" is an NSOutputStream. I would greatly appreciate your insight on this.
-(NSData *)sendDataReturningResponse:(NSData *)data error:(NSError **)error
{
//Write the data to the output stream.
int retval = [os write:[data bytes] maxLength:[data length]];
//retval will be -1 if an error has occurred.
if (retval == -1)
{
*error = os.streamError;
NSLog(@"%@", [os.streamError localizedDescription]);
return nil;
}
else
*error = nil;
NSMutableData *response = [[NSMutableData alloc] initWithCapacity:0];
//Wait for response to come back.
while (response.length < 1024)
{
if ([is hasBytesAvailable])
{
uint8_t buf[MAX_RECV_SIZE];
unsigned int maxlen = 0;
maxlen = [is read:buf maxLength:MAX_RECV_SIZE];
[response appendBytes:(const void *)buf length:maxlen];
}
else
{
sleep(.1); //No data available on the input buffer. Sleep for 100ms and we'll try again.
}
}
return [response autorelease];
}
>
> Cheers,
> Ken
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden