|
The following recipe correnspond to the (pseudo) extraction of numbers from a bag:
<ol>
<li>Create an array containig all the candidate numbers, for instance <code>int value[]={1,2,3,4,5,6,7,8,9,10};</code>,
initialize a variable that will keep track of the sequence length, for instance <code>len=10;</code></li>
<li>make an loop for how many numbers you wish to extract, at each cycle</li><ol>
<li>select an index number via <code>index = (int)( (double)rand() * len / RAND_MAX);</code></li>
<li>keep the number corrensponding to the index, for instance <code>num = value[index];</code> that is you extracted one.</li>
<li>swap the index selected with the one at the (the current) bottom of the array, i.e. <code>swap(value[index], value[len-1]);</code></li>
<li>decrement <code>len</code>;</li>
</ol>
</ol>
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
|
My TCP/IP server(a dialog based MFC/VC app developed using CAsyncSocket class) is supposed to send 76800 bytes of data to the client which is a gsm modem(baud set at 57600 bps) which receives the data via gprs. i split it up into 240 packets of 320 bytes each.
The problem i am facing is loss of data at the client. I tried introducing delay(1s to 5s) at the server after sending each packet. Still the whole set of 76800 bytes never reach the client.
If i introduce an ACK from the client after receiving each paket and make the server to send the next packet only after RXing the ACK, then there is NO loss of data but it takes a long time(8to13 minutes) for the whole data transfer. My afordable time space is 40secs.
I am looking for a solution where the server can make sure when each packet(of 320 bytes) has reached the destination so that the next packet can be sent.
It would be extremely kind of you if you could help me up solve the issue. Pls let me know if any part is unclear.
(Note: The bytes are pixel data of a 240 x 320 resolution image, 8 bits per pixel.)
|
|
|
|
|
Don't know why you get data loss, you shouldn't need to send your own ACK-s back since TCP should handle that by itself, don't know the GPRS protocol. Anyways, you could try sending less but bigger packets, so for example try sending the pixel data in 4 or maybe 2 packets instead of 240. That should lessen the time needed for the transfer. You could also consider using compression instead of sending uncompressed pixel data over.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
If you look at the TCP section in the IBM TCP/IP redbook[^] (warning - it's a 6MB PDF, but well worth the download), you'll see that the TCP layer should handle all the ACKs and stuff for you. You'll also see that it's a stream oriented protocol - which means that it's probably best if you send all 76800 bytes in one go - the TCP layer should ensure that the data gets split into packets, each packet transmitted and received and the data reconstructed correctly. It sends a set of packets, assuming successful transmission, and doesn't expect an ACK immediately (as you've seen, the ACKs aren't immediate!) - it sets a timeout for each packet, and expects the ACK before the timeout occurs.
Splitting your data up into bits stops TCP doing its job so easily, and is probably better suited to a datagram oriented protocol like UDP.
As I said before, the IBM redbook is a very good resource that helps you understand networking technology better, which should help you design networking apps better.
One last thing - there may be some options that need be set using setsockopt to optimise your TCP/IP stack for your transport layer (the GSM modem), as it's quite slow?
HTH!
|
|
|
|
|
As suggested by you frends, i made it a single packet of 76.8 kB instead of 240. It works perfectly. Just that the time taken depends on the gprs speed and connectivity (31 secs to 2 mins in 10 trials).
Thanks a lot:
Randor
Sturat Dootson &
Cod-o-mat
for the help and support.
|
|
|
|
|
Shameer E.A. wrote: As suggested by you frends, i made it a single packet of 76.8 kB instead of 240
Happy to hear that it worked for you. Did you enable RFC 1323?
You should know that you are actually sending more than 1 packet if you are using the default TCP window size.
Best Wishes,
-David Delaune
|
|
|
|
|
No David, I didnt enable RFC 1323.
I just sent it using CAsyncSocket::Send() command once.
i see that the TCP/IP protocol breaks it up into packets when using the default TCP window size.
ThanQ David.
|
|
|
|
|
Hi Shameer,
I have done some marine industry related GPRS socket programming and have battled the same problem. You may want to check if your modem and upstream provider supports TCP Window Scaling[^] as defined in RFC 1323[^]. This will allow you to send packets larger than 64K. In fact you could send all of your data in a single packet. Or is there a reason that you need to send 240 packets at 320 bytes each?
Light travels at a maximum of 299792458 meters per second to the satellite, actually slightly slower in the Earth atmosphere. Sending only 320 bytes each packet in a high-loss environment will increase the SYN-ACK/RESEND cross-talk. This will probably result an increased transmission time. Sending larger packets may be your answer.
Best Wishes,
-David Delaune
|
|
|
|
|
I'm looking for an ADT, that's like a set, only I need to be able to search for an item through 2 different keys, a timestamp and its ID. The reason is because each item in the container is victimized in LRU fashion (timestamp) but gets referenced by its index (where the timestamp gets updated).
Suggestions?
[update]
Never mind. Worked using Boost's Multi-Index set.
modified on Saturday, December 20, 2008 6:55 AM
|
|
|
|
|
[edit]Well, that was good timing - between the time I started and posted this, you added your update about Boost.MultiIndex - DOH![/edit]
Something like Boost.MultiIndexwould fit the bill. I've used it, it allows you to index a collection of objects in multiple ways. It can be a bit difficult to work out how to get started with it (extreme template madness!), but it is very easy to use after that. Just make sure you're NOT trying to use it with VC6 - that's a sure path to insanity.
The other way is to do it yourself (this I have also done!). The easiest way is to emulate what Boost.MultiIndex does. Hold the index in some collection, then present multiple indices of that collection. I managed the objects using Boost shared_ptrs, like so:
class SomeObject { class-implementation };
class MultiIndexCollection
{
typedef boost::shared_ptr<SomeObject> SomeObjectPtr;
typdef std::vector<SomeObjectPtr> SomeObjects;
void AddObject(SomeObject const& o) { someObjects_.push_back(SomeObjectPtr(new SomeObject(o))); }
SomeObjects const& GetIndex1() const { return index1_; }
. . . . .
SomeObjects const& GetIndex1() const { return indexn_; }
void ReIndex() { reconstruct the indices by sorting them };
private:
SomeObjects someObjects_;
SomeObjects index1_;
. . . . .
SomeObjects indexn_;
};
I was lucky enough that the app could be split into two phases - object insertion and object lookup, so I could handle re-indexing at a point in the app's lifetime. If you can't do this, things are a bit trickier. You could do something like have a 'dirty index' flag, which you set true when AddObject is called. Index retrieval would then trigger a re-index if this 'dirty index' flag is set true. The problem with this is that the performance spikes implied by re-indexing aren't as visible or predictable, as they're hidden inside the index getters.
The re-indexing sorts the object pointers based on some criteria. After indexing, you can use the indices with a binary search, as they've been sorted.
BTW - using sorted vectors as indices like this has, I believe, been shown to be more efficient than (say) std::map s for this use case.
After seeing this, you may well just plump for the Boost.MultiIndex approach...I probably would now, I suspect - it's just that I wrote the above app with VC6, so most Boostyness was out of bounds. And by the time I upgraded to VC7.1, the app was mature enough that I wasn't going to bother going back and changing it - it ain't broke, I'm not fixing it!
|
|
|
|
|
Its cool
Besides, there's an issue I discovered that you might be kind enough to help me out with.
this is the error I'm getting when compiling:
error C2039: 'push_back' : is not a member of 'boost::multi_index::multi_index_container<value,indexspecifierlist>'
and this is what's throwing it:
copy(cacheSets[i].SetBlocks.begin(), cacheSets[i].SetBlocks.end(), back_inserter(miCache));
when the example provided on the boost website is:
std::copy(tok.begin(),tok.end(),std::back_inserter(tc)); Clickety[^]
I think I'm over complicating things. Mind if I email you? To my shame, it is a homework question that has been driving me insane
|
|
|
|
|
hi all,
i have any rect value.
for first line its correct.
but for second line its overlapping from 1st one.
how can i change its value by this its go to next line.
please help me for this.
thanks in advance.
IN A DAY, WHEN YOU DON'T COME ACROSS ANY PROBLEMS - YOU CAN BE SURE THAT YOU ARE TRAVELLING IN A WRONG PATH
|
|
|
|
|
Can you more explain?
Of one Essence is the human race
thus has Creation put the base
One Limb impacted is sufficient
For all Others to feel the Mace
(Saadi )
|
|
|
|
|
i m using this.
<br />
CDC* pDC;<br />
CRect rect;<br />
pDC->DrawText("Test", rect, DT_LEFT | DT_BOTTOM);<br />
for first line its rite when i draw text for next line its overlapped from first line.
IN A DAY, WHEN YOU DON'T COME ACROSS ANY PROBLEMS - YOU CAN BE SURE THAT YOU ARE TRAVELLING IN A WRONG PATH
|
|
|
|
|
Well, try something like:
<br />
rect.OffsetRect(0, pDC->DrawText("Test", rect, DT_LEFT | DT_TOP | DT_SINGELINE));<br />
Or simply make your string contain all the lines separated with \n -s and draw them with one call to DrawText.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
in DrawText if text is greater than one line than how can show it in multiple lines.
IN A DAY, WHEN YOU DON'T COME ACROSS ANY PROBLEMS - YOU CAN BE SURE THAT YOU ARE TRAVELLING IN A WRONG PATH
|
|
|
|
|
DT_WORDBREAK, and don't use DT_SINGLELINE with it. But you should read the documentation[^] before asking questions here.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
For DrawText im getting text value from ListCtrl.
here if in any column the text is greater than column width or if minize the width of column than it takes only text which is displya not all text of column.
for this condition please tell me what can i do
and how can i show any image by this.
IN A DAY, WHEN YOU DON'T COME ACROSS ANY PROBLEMS - YOU CAN BE SURE THAT YOU ARE TRAVELLING IN A WRONG PATH
|
|
|
|
|
I don't quite understand what you mean...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
I mean,
I m using a List Ctrl from where i m fetching a details of diffrent rows and columns.
Text is displayed in single line in ListCtrl.
if text length is greater than width of column than it is not fully visible in column and same it is not print fully.
so tell me how can i get full data of column whereas it is fully visible in column or not.
And i want to print bmp also please tell me how print a bmp.
please help me for this,
thanks in advance.
IN A DAY, WHEN YOU DON'T COME ACROSS ANY PROBLEMS - YOU CAN BE SURE THAT YOU ARE TRAVELLING IN A WRONG PATH
|
|
|
|
|
I still don't quite get what you want, what do you mean by "get data from column"? You want to know the size needed to display all the text in a given row and column? Use either GetTextExtent or DrawText with DT_CALCRECT, look these up in the docs.
To draw a bitmap you will need to make a memory DC, select the bitmap into it and then use BitBlt to render it onto whatever you want to render it onto.
So something like this:
CDC MemDC;
MemDC.CreateCompatibleDC(&your_target_dc);
CBitmap *OrigBitmap = MemDC.SelectObject(&the_bitmap_you_want_to_display);
your_target_dc.BitBlt(0, 0, bitmap_width, bitmap_height, &MemDC, 0, 0, SRCCOPY);
MemDC.SelectObject(OrigBitmap);
But you can find this also in the documentations all around the net, Google is your friend.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
I m use this(DT_CALCRECT) in DrawText but when i use this the text is not displayed.i dont know how?
IN A DAY, WHEN YOU DON'T COME ACROSS ANY PROBLEMS - YOU CAN BE SURE THAT YOU ARE TRAVELLING IN A WRONG PATH
|
|
|
|
|
If you'd read the documentation you'd know that DT_CALCRECT won't actually display the text but only measure its extent.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Code-o-mat wrote: CDC MemDC;MemDC.CreateCompatibleDC(&your_target_dc);CBitmap *OrigBitmap = MemDC.SelectObject(&the_bitmap_you_want_to_display);your_target_dc.BitBlt(0, 0, bitmap_width, bitmap_height, &MemDC, 0, 0, SRCCOPY);MemDC.SelectObject(OrigBitmap);
I m try this its works,but the image diplayed very-very small thats why its not properly visible.
please tell me what can i do for this.
IN A DAY, WHEN YOU DON'T COME ACROSS ANY PROBLEMS - YOU CAN BE SURE THAT YOU ARE TRAVELLING IN A WRONG PATH
|
|
|
|
|