Re: A NSOutputStream vs. native socket question
Re: A NSOutputStream vs. native socket question
- Subject: Re: A NSOutputStream vs. native socket question
- From: Motti Shneor <email@hidden>
- Date: Thu, 14 Nov 2013 22:58:50 +0200
On 14 בנוב 2013, at 21:10, Josh Graessley wrote:
>
> On Nov 14, 2013, at 10:53 AM, Motti Shneor <email@hidden> wrote:
>
>> Hi Everyone. First post to this group.
>>
>> I'm controlling the output stream created by
>>
>> ::CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)hostAddress, portNum, &readStream, &writeStream);
>> ::CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
>> ::CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
>>
>> and later bridged to NSInputStream and NSOutputStream instances,
>> via its internal native socket, using the posix getsockopt and setsockopt calls.
>>
>> The properties I need to work with are the read (input) and write (output) buffer sizes, and the write (output) socket's buffer pending content size.
>>
>> Things like this...
>> oss = getsockopt(socket,SOL_SOCKET,SO_RCVBUF,&value,&valueSize);
>> oss = setsockopt(socket,SOL_SOCKET,SO_SNDBUF, &value, sizeof(value);
>> oss = getsockopt(socket,SOL_SOCKET,SO_NWRITE, &value, &valueSize);
>>
>> etc.
>>
>> To retrieve the native socket I'm using code like this:
>>
>> // Getting the amount of bytes in the output socket buffer which are waiting to be sent
>> - (int) getSocketOutputBufferPendingSize:(uint32_t*)bufSize {
>> int oss = -1;
>> CFDataRef data = NULL;
>> do {
>> if (_outputStream==nil)
>> break;
>>
>> // retrieve native socket handle from output stream.
>> if((data = (CFDataRef)::CFWriteStreamCopyProperty((CFWriteStreamRef)_outputStream, kCFStreamPropertySocketNativeHandle))== NULL)
>> break;
>>
>> CFSocketNativeHandle socket;
>> CFDataGetBytes(data, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8*)&socket);
>> .
>> .
>> . // --- here I work with the native socket properties.
>> .
>> } while (false);
>>
>> if(data!= NULL)
>> ::CFRelease(data);
>> return oss;
>> }
>>
>> My questions are:
>>
>> 1. What is the lifespan of the native socket handle?
>> 2. Can I retrieve it once, when the socket is created or opened the first time, then use it until socket is closed, or should I retrieve it from the stream like this, every time I want to use it?
>> 3. What is the cost of the above lines that retrieve the native socket handle?
>
> I hate to answer a question with another question, but…
>
> Why are you modifying SO_SNDBUF? Modifying SO_SNDBUF and SO_RCVBUF means the system can’t dynamically adjust these values based on network conditions. If you’re hand tuning these values, that might have a small improvement in performance in one network environment but it is likely to have a negative performance impact in other environments.
>
> Fetching the native file descriptor out of the socket stream does work but it doesn’t come without cost.
>
> -josh
>
Hi Josh. I will answer your question, but could I please ask you to also provide some answer to mine?
In the organization I'm working for (as a contractor), we're using an old, (and dare I say wracked) "socket" implementation which maintains its own message queue on a cyclic buffer, from which it draws data and writes it to the NSOutputStream's socket.
This socket's design and most of its implementation are taken from an even-older C++ Windows (sigh) implementation over a windows native socket who is opaque and provides no information neither about the size of its buffers, nor of their current contents size.
Under those historical windows-imposed considerations, the only way to have reasonable bandwidth measurements (how much was pushed through the network in the last second, and what is the "delay" of data in "our side" of the server connection) is by reducing the size of the socket's internal (opaque) buffers, in comparison with the external socket queue, and do the measurements on OUR queue.
When the system socket's internal buffers are small and there is a network bandwidth problem --- we know it early, by failing to write new data into the system socket.
OF COURSE THIS IS A BAD IMPLEMENTATION.
However, I'm a contractor, hired to debug old code, and I can only recommend on enhancing (actually deleting) this old socket code. This is nontrivial because this socket code is doing much more than what I said, and is tightly bound to the specific protocol running between the server and client. It also implements non-standard encryption, nonstandard proxy interactions, and most important -- same socket code runs on server (Windows) and all sorts of clients. In time, I may be called to replace it with better implementation.
I know of a good way, using the SO_NWRITE property, to provide good network bandwidth measurements WITHOUT altering the native socket buffer sizes, but I will need to read this property pretty often --- hence my question. What can I do once-per-native-socket and what do I need to do regularly?
Motti Shneor,
---
ceterum censeo microsoftiem delendam esse
---
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden