Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

bounded buffer

0 views
Skip to first unread message

Larry

unread,
Jan 23, 2010, 1:38:46 PM1/23/10
to
Hi,

I am writing a little application to capture audio data from a wavein
device and broadcast it to the

internet over http protocol. My application is basically divided into two
segments:

Capturing Thread:
-> waveCapture // waveCapture.h (class)
-> mp3Encoding // mp3Encoder.h (class)

Broadcasting Thread:
-> httpServer // httpServer (class)

So in a nutshell, the capturing thread is the "Producer" and the
broadcasting thread is the "Consumer".

In order to link them I need to code a buffer. The producer will put data on
it whereas the consumer will

retrieve data from it.

I would like to post some code about the server (barebones) so I can get to
the main point later on:

unsigned int __stdcall handleClient(void* a)
{
Socket* s = (Socket*) a;
while(1)
{
string r = s->ReceiveLine();
if (r.empty())
break;

s->SendLine("Hello, I am the server!");
break;
}

// Disconnect
s->close();

delete s;
return 0;
}

int main()
{
// Server: set up
SocketServer in(8000,5);

while(1)
{
// Server: wait for incoming connections
Socket* s=in.Accept();
cout << "a client connected..." << endl;

// Server: spawn a new thread to deal with the client
unsigned int ret;
_beginthreadex(0,0,handleClient,s,0,&ret);
}

system("pause");
return EXIT_SUCCESS;
}

As you can see, the server waits for incoming connections and spawns a
thread to deal with a single client each time it connects.

Now, in the handleClient() thread I should retrieve data from the buffer
(being written by the "producer") and send it to the client...

Here comes the pain! Since I have to deal with several connections at the
same time I don't know if they should read from one single buffer or
something else...for instance the producer should write to severl instances
of the buffer...

any idea how I should work this out?

thanks

Yu Han

unread,
Jan 23, 2010, 11:26:33 PM1/23/10
to
On 01/24/2010 02:38 AM, Larry wrote:
> Hi,
>
> I am writing a little application to capture audio data from a wavein
> device and broadcast it to the
>
> internet over http protocol. My application is basically divided into
> two segments:
>
> Capturing Thread:
> -> waveCapture // waveCapture.h (class)
> -> mp3Encoding // mp3Encoder.h (class)
>
> Broadcasting Thread:
> -> httpServer // httpServer (class)
>
> So in a nutshell, the capturing thread is the "Producer" and the
> broadcasting thread is the "Consumer".
>
> In order to link them I need to code a buffer. The producer will put
> data on it whereas the consumer will
>
> retrieve data from it.
>
> I would like to post some code about the server (barebones) so I can get
> to the main point later on:
>

// all code are in the server
// all locks are omitted
struct Buffer
{ ... };

list<Buffer*> clients;

unsigned int copyBuffer(void*)
{
while (1)
{
// read data from producer
// copy data to every client in the list


}
}
> unsigned int __stdcall handleClient(void* a)
> {

Buffer buf;
registe(buf); // insert buf to the clients list


> Socket* s = (Socket*) a;
> while(1)
> {
> string r = s->ReceiveLine();
> if (r.empty())
> break;
>
> s->SendLine("Hello, I am the server!");

// read buf and send it


> break;
> }
>
> // Disconnect
> s->close();
>
> delete s;

unregiste(buf); // Is the parameter necessary?


> return 0;
> }
>
> int main()
> {
> // Server: set up
> SocketServer in(8000,5);

beginthreadex(0,0,copyBuffer,0,0,0);


>
> while(1)
> {
> // Server: wait for incoming connections
> Socket* s=in.Accept();
> cout << "a client connected..." << endl;
>
> // Server: spawn a new thread to deal with the client
> unsigned int ret;
> _beginthreadex(0,0,handleClient,s,0,&ret);
> }
>
> system("pause");
> return EXIT_SUCCESS;
> }
>
> As you can see, the server waits for incoming connections and spawns a
> thread to deal with a single client each time it connects.
>
> Now, in the handleClient() thread I should retrieve data from the buffer
> (being written by the "producer") and send it to the client...
>
> Here comes the pain! Since I have to deal with several connections at
> the same time I don't know if they should read from one single buffer or
> something else...for instance the producer should write to severl
> instances of the buffer...
>
> any idea how I should work this out?
>
> thanks


--
Yu Han

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Larry

unread,
Jan 24, 2010, 6:47:19 AM1/24/10
to
"Yu Han" <hanj...@163.com> ha scritto nel messaggio
news:hjgica$2snc$1...@adenine.netfront.net...

> // all code are in the server
> // all locks are omitted
> struct Buffer
> { ... };
>
> list<Buffer*> clients;
>
> unsigned int copyBuffer(void*)
> {
> while (1)
> {
> // read data from producer
> // copy data to every client in the list
> }
> }

wow that seems a great step into the right direction! Yet, why you think I
should prefer <list> over <vector> ??

Also, I'm in two minds whether I should delete the chunk from the buffer
after reading it or just read it and let the "Producer" overwrite it
eventually. (is this circular buffer?)

so that when a client connects a new buffer is being pushed_back into the
vector...then the producer will write to all the buffers in vector.

Yu Han

unread,
Jan 24, 2010, 8:59:36 AM1/24/10
to
On 01/24/2010 07:47 PM, Larry wrote:
> "Yu Han" <hanj...@163.com> ha scritto nel messaggio
> news:hjgica$2snc$1...@adenine.netfront.net...
>
>> // all code are in the server
>> // all locks are omitted
>> struct Buffer
>> { ... };
>>
>> list<Buffer*> clients;
>>
>> unsigned int copyBuffer(void*)
>> {
>> while (1)
>> {
>> // read data from producer
>> // copy data to every client in the list
>> }
>> }
>
> wow that seems a great step into the right direction! Yet, why you think
> I should prefer <list> over <vector> ??
use what is suitable, not what I/you prefer. In fact, it's possible that
neither is suitable.

>
> Also, I'm in two minds whether I should delete the chunk from the buffer
> after reading it or just read it and let the "Producer" overwrite it
> eventually. (is this circular buffer?)
Maybe a circular buffer is better, maybe...

>
> so that when a client connects a new buffer is being pushed_back into
> the vector...then the producer will write to all the buffers in vector.
>

I don't know all the things about your application. You should make
decision according to your situation. Then, try, test and tune it.

Larry

unread,
Jan 25, 2010, 10:00:37 AM1/25/10
to
"Yu Han" <hanj...@163.com> ha scritto nel messaggio
news:hjhjus$1ddr$1...@adenine.netfront.net...

> Maybe a circular buffer is better, maybe...

Do you think the following could be fine approach?

// declare
typedef unsigned int regkey;
typedef struct {...} buffer;

// global buffer
std::map<regkey, buffer> clients

// a client connect (add consumer)
clients.insert(makepair(regkey, buffer));

// a client disconnect (remove comsumer)
clients.remove(regkey);

// Producer writes to every element in the map(clients)
(...)

thanks

Yu Han

unread,
Jan 25, 2010, 8:26:49 PM1/25/10
to
On 01/25/2010 11:00 PM, Larry wrote:
> "Yu Han" <hanj...@163.com> ha scritto nel messaggio
> news:hjhjus$1ddr$1...@adenine.netfront.net...
>
>> Maybe a circular buffer is better, maybe...
>
> Do you think the following could be fine approach?
>
> // declare
> typedef unsigned int regkey;
> typedef struct {...} buffer;
could you show the body?

>
> // global buffer
> std::map<regkey, buffer> clients
Why not a buffer*?
In your case, buffer must be well defined...

>
> // a client connect (add consumer)
> clients.insert(makepair(regkey, buffer));
>
> // a client disconnect (remove comsumer)
> clients.remove(regkey);
>
> // Producer writes to every element in the map(clients)
> (...)
>
> thanks

--

0 new messages