Server implementation questions
Server implementation questions
- Subject: Server implementation questions
- From: Chris Hanson <email@hidden>
- Date: Thu, 3 Apr 2003 17:14:58 -0600
I'm writing an application on Cocoa that includes its own simple
server, and I'm trying to figure out how to structure some of it.
I can implement the network server itself pretty much in my sleep.
It's simple: Create a socket, listen on it, create an NSFileHandle
for it, to accept connections on it use
-acceptConnectionInBackgroundAndNotify, to read from an accepted
connection's file handle use -readInBackgroundAndNotify, to write to
it use -writeData:, to stop listening or close an accepted connection
use -closeFile, etc. Like I said, simple. I don't even need to use
threads.
I have two questions, and a bonus question.
*** Question 1: How do I determine if an NSFileHandle I'm reading
from has available data *without* blocking?
I don't want to use -[NSFileHandle
readToEndOfFileInBackgroundAndNotify] because this opens the user up
to a denial-of-service attack. Will using -[NSFileHandle
readDataOfLength:] to read 0 bytes return nil immediately for a
closed socket and an empty NSData immediately for an open socket
regardless of whether data is available? And is that behavior I can
count on?
*** Question 2: How should I go about writing code that, from the
same application, connects to the server *without* the headache of
using threads?
I want to be able to write unit tests using OCUnit for this code.
(In fact, I'm doing test-driven development for a good bit of this
application.) If I write my unit test like this
-(void)testServerRequestResponse
{
// start up the server
fd = socket(...);
err = connect(fd, ...);
err = write(testRequestBuffer, ...);
err = read(&testResponseBuffer, ...);
err = close(fd);
// compare the response to the expected response
}
it seems that as soon as the test hits the call to connect(2) the
application will deadlock. I don't really want to use a separate
thread for this either, since I can't just pause execution of this
unit test until the thread is over without the same deadlock issue.
*** Bonus Question 1: If the answer to Question 2 is "You need to
use a separate thread for the server," it means I'm going to have to
write a bunch of raw socket code (or use one of the many wrapper
classes). That's not a huge problem, but how can I shut down the
server while it's listening? If I close(2) the listening/accepting
file descriptor from within the main thread, will accept(2) just
return -1 in the server thread?
In writing this, I suspect that I'm going to have to implement the
server in a separate thread, and that I'm right about using close(2)
in the main thread to terminate a server thread blocked in accept(2).
Either that, or I'm going to have to write everything using
non-blocking sockets and select(2), and figure out some other
mechanism to tell the server thread to stop.
-- Chris
-- who really wishes at times for Open Transport's wonderfully useful
asynchronous notifier approach to networking
--
Chris Hanson, bDistributed.com, Inc. | Email: email@hidden
Custom Application Development | Phone: +1-847-372-3955
http://bdistributed.com/ | Fax: +1-847-589-3738
http://bdistributed.com/Articles/ | Personal Email: email@hidden
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.