Howto get available space left of internal writebuffer of a socket [win32]

Started by
11 comments, last by Anon Mike 19 years, 3 months ago
Hi, Could anybody please help me with how to get the state of the internal writebuffer of a socket under windows. In other words, how many bytes are left in the internal writebuffer of the socket. The only thing I could find was how to set and get the internal writebuffer size with WSAIoctl. Okee, a little story about the project. I am making a VFW video capture, MPEG4 encoder, tcp streaming ActiveX component. Everything is written in pure C++ and win32. So no (censured) MFC or ATL ;). Before I encode a mpeg4 frame I have to know if I can send the frame. Because a MPEG4 frame is the difference between the current and the previous frame, except for GOP frames. Thanks a lot and happy new year, Bagwani [Edited by - bagwani on December 31, 2004 1:23:22 PM]
Advertisement
Well, the best I can come up with is if a socket is ready to write. Here is the c++ snippet.

bool CanWrite( int SocketDescriptor){    if( SocketDescriptor == 0 )    {        return false;    }    fd_set writefds;    FD_ZERO( &writefds );    FD_SET( SocketDescriptor, &writefds );     int result = -1;    result = select( SocketDescriptor, 0, &writefds, 0, 0 );    return ( 0 == result );}


But I still don't know how MUCH I can write to the socket. Anybody can help me out with that???

[Edited by - bagwani on December 31, 2004 10:52:43 AM]
You can't know.

Why do you need to? I mean, if you were told "trying to send this frame will block the current thread for some time", what would you do differently?
enum Bool { True, False, FileNotFound };
I'm debugging a program where I use sockets (with MFC) and I test if all the data has been sent over the socket checking the result of send. I'll translate avoiding MFC. For example:

int nBytesToSend=1000;char * pBuffer=new char[nBytesToSend];int nBytesSent=send(hSocket,pBuffer,nBytesToSend,0);if (nBytesSent<nBytesToSend)    nBytesLeftToBeSend=nBytesToSend-nBytesSent;   // <- your value of interest?

If this answer is not what you're expecting, I try one another [embarrass].

getsockopt with parameter SO_MAX_MSG_SIZE tell you the max size of a message (I think that's the size of the internal buffer) and when send return the error code WSAEMSGSIZE, you know that nothing is sent. So with simple substraction you'll know how many bytes of SO_MAX_MSG_SIZE are left.

Hope that's help.
Fil (il genio)
@hplus0603

I forgot to mention my sockets are in non-blocking mode. If I write to the socket, it will never be blocked.

@Fill

The problem is that I must send the whole mpeg4 encoded frame or not. If I send it partially, I screw up the decoder on the other end. So If I could peek in the internal writebuffer of the socket, I know if there is a queue building up and can avoid of sending incomplete MPEG4 frames. BTW I'm using FFMPEG for the en/decoding.

I am also programming under unix and linux. And there it is possible to look at the available space left of the internal writebuffer of the socket.

@both

Thanks for the input

[Edited by - bagwani on December 31, 2004 12:26:28 PM]
@Fil: When send() returns, that just means the data has been copied to internal buffers, it's not guaranteed that the data is at the other end, or has been acknowledged.


@bagwani: I still don't understand what the difference between "enough buffer space" or not, is. Why would the decoder be confused? Are you using TCP or UDP? If you're using UDP, you'd have to worry about packet loss and stuff anyway, so fragmenting packets wouldn't be a problem. If you're using TCP, you have to realize that it's a stream protocol, and thus you are NOT guaranteed to get a single packet of 200 bytes out one end if you write a single packet of 200 bytes on the sending side -- you might get two packets of 100 out, or one packet of 300 (if you had first written 100 bytes before the 200 bytes).

I'm guessing you're using TCP. TCP is a stream protocol. For your protocol to work right (i e, deliver "whole frames") you have to introduce your own framing. Thus, each time you write data, you first write a length, and then write that many bytes of data. On the receiving side, you read a length, and then that many bytes of data.

I still don't understand what you would do if you wouldn't write the data, though. If the link is lower bandwidth than the data rate of your video, then what? What if there's temporary congestion and the link dries up for a few seconds?
enum Bool { True, False, FileNotFound };
just wondering TCP is streaming

that means it guarantees your packages will arrive and they will arive in the correct order


so all you do is create a timer to not overflow your connection and then simply send your data this needs some tweaking though but should work for what you are going to do

i am not sure but i think you can get the max packet size somehow just look up the msdn
http://www.8ung.at/basiror/theironcross.html
TCP guarantees that the data STREAM will arrive in order, even if it takes a 10 second stall of re-transmits to get it there.

Also, it guarantees that the ordered data gets there -- it does NOT guarantee that any specific packets get there. Thus, if you send(100 bytes) and then send(200 bytes) and then send(300 bytes), the other end may see 12 packets of 50 bytes each, or one packet of 600 bytes, or anything inbetween -- it's only the sequence of bytes that matters.

TCP implementations will typically coalesce successive writes, and, when packet re-transmits happen, coalesce packets waiting to be sent.
enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
@Fil: When send() returns, that just means the data has been copied to internal buffers, it's not guaranteed that the data is at the other end, or has been acknowledged.


Sorry if I take advantage of this thread to ask what can be done to be sure data has been acknowledged. If the other end does a send() to tell me it has received my data, it is possible I can never receive it. (This could help me in solving a problem on the program on my thesis, if you want I can begin another thread).
Fil (il genio)
Fil, please start another thread.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement