|
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
|
|
|
|
|
Use CDC::StretchBlt[^], but be carefull with that because it seems not all printer drivers support it.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
if i want to load bitmap from browse path,how can i use here.
IN A DAY, WHEN YOU DON'T COME ACROSS ANY PROBLEMS - YOU CAN BE SURE THAT YOU ARE TRAVELLING IN A WRONG PATH
|
|
|
|
|
By using the magical tool, Google and finding this[^] with it.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|