Wow, what an incredible reply. I don't understand everything you wrote, but a question or two will help.
This is a telemetry application. It receives data from the hardware as a series of identified parameters. It extracts messsages from within the list of parameters and sends the data to the display device. It outputs data via TCP/IP to the display device, but does not input anything via TCP/IP.
When I switched to asynchronous TCP/IP I discovered about WOULDBLOCK and created an array that buffers data until OnSend is called. That worked OK at relatively slow packet rates, two per milliseconds.
Upon adding in another set of payload packets (there are several types of payload packets that can be inhibited or enabled at run time) the payload packet rate jumped up to five to fifteen or so payload packets per millisecond. They are generally smaller packets, but the order is indeterminate so it is very intensive to combine payload packets to reduce the overall payload packet rate.
When that happened, the app ran out of buffer space and started loosing payload packets. I bumped up the buffer size from 16, to 32, to 64, then jumped to 240. It still overflowed.
My interpertation is that CAsyncSocket cannot keep up with this packet rate. When I use blocking TCP/IP calls it works okay. I can even run four simultaneous copies with no trouble.
As I understand your post, I am thinking that this probably cannot be accomplished with CAsyncSocket.
If that a true or false statement?
Don't write too much, I will certainly need to think a while, and re-read your post depending on how you answer this question.
As I see you just get some data somewhere and send it over to another place, your app is a transmitter between 2 endpoints. This is quite simple fortunately. If you are not allowed to drop data then your send speed must be at least as big as your receive speed. A buffer helps only in smoothing away jitter in the incoming data to maintain a better average throughput. If your incoming data is more than what you can send then the problem can not be solved. If you are able to reach the required send speed with blocking you should be able to do the same with async as well. Anyway, why do you want to use async sockets?
Hello pasztorpisti, Re: Anyway, why do you want to use async sockets? Async makes the application easier to deal with. First, when the client has not connected the main application can still capture data from the source and provide feedback as to how it is performing. Once the Listen() is posted, the app is stuck there and can do nothing. Second, if the client closes the connection before my app closes, the app is stuck and must be killed. That causes some resource loss eventually requiring a computer boot.
I have mitigated that quite a bit by writing my own client application that can be fired up and release the main application. But I am not always the user and that is a real pain to require someone else to do. (BTW: Writing the client application was indeed a learning experience.)
I suspect that both of these problems can be resolved by using a separate thread for the TCP/IP part of the application. I found a tutorial and will be working on that aspect.
However, I have a working version and do not have unlimited time to devote to this project.
pasztorpisti, Richard M, and others, Thank you very much for the time you have spent answering my questions and making suggestions. I am very gratefull.
You are welcome! If you have limited time (as I suspected) then choose a working solution of yours if you already have one. You can later experiment on better solutions if you are interested in threading/sockets.
Unfortunately I don't know about any good tutorials because I'm not in need of one. I learnt from teammates and from my own experiments. You dont always benefit from dedicated threads, that depends on the scenario but you can not find that out without trying.
This is a great answer, I really wish I could vote on it.
Networking is always tricky
You are totally correct. It looks so simple and we use networking applications all the time, but as soon as you have to do a bit more than a basic chat sample, small surprises crop up all over and you start racking up on "experience points" as you try to solve them .
Soren, You are quite right. It is easy for forget, and much easier to never even realize, just how much effort has gone into writing the core code within the Operating Systems that we use every day without realizing how much goes on that we do not see.
It is easy to complain about Microsoft or any other OS. The reality is that all of them do a quite difficult job very well.
Thank you! Pretty much all areas of programming can become tricky if you cross the line. I've always considered myself a generalist programmer and I'm definitely not a network expert. I've just had the luck to work on some specialized networking apps.
The programmer creates the overrides such as OnAccept(). Here is a fragment from elsewhere on this site:
void MyEchoSocket::OnAccept(int nErrorCode)
// TODO: Add your specialized code here and/or call the base class
Note that the comment says and/or. The question is: Is there a need to have the call CAsyncSocket::OnAccept()? In the over-ride code can I just execute what I want done and forget that call to CAsyncSocket::OnAccept()?
As you see it doesn't count whether you call it or not but in my opinion its always better to upcall base class methods when you are not sure what to do and the upcall doesn't do any harmful thing to your code. In this case its unlikely that MS changes the implementation of such a core class but generally when you use others' classes as a baseclass its better not to build anything on assumptions. Imagine what happens if you refactor your socket code and you change the baseclass of your socket class from CAsyncSocket to another socket class of yours that does something meaningful in OnAccept()... So here I recommend the upcall as I think its a good practice.
In general, you do want to call the base class method (be careful of when you call it, sometimes it's appropriate to do it before your code, sometimes you want to do it after your code).... in certain cases, it doesn't matter (it's an empty place holder) or you don't want the default behavior of the base class at all, in which case you don't call it at all.
If you don't call the base class method, be sure you know why you're not calling it because sometimes the methods will do things in the background that are important to the operation of the base class.
This is a telemetry application where data arrives in a continuous stream. My application breaks that data out into named parameters and sends it to a display device. It generates at least two packets per millisecond and often ten or more.
As a result I will check to see if I can find any operations performed by the base class. When there are none time is saved by not making the call.
I do worry that they may be things done by that call that I do not have visibility into, hence the question.
While working with some checkboxes I made an error and created the event handler in an incorrect class. I think I have recovered from that. But maybe not completely.
Now after creating a checkbox, the right click and Add Variable option is grayed out. I have tried deleting the following files: .ncb and .suo and .user and .aps, and deleted directory Debug. After a Clean and Rebuild the problem remains. Does anyone have any suggestions as to how to resolve this problem?
There is no point in randomly deleting files unless you understand their purpose. It may be that you have left some unconnected data that is confusing the class wizard, which holds its information in the .clw file. However, make sure you keep a backup copy of this file before deleting it.
One of these days I'm going to think of a really clever signature.
Yes, that is a good article. I just wanted to know how many copies have already been started so the code could avoid putting all the opwninf dialogs on top of each other. I will elect to not add that complexity and let the user deal with it. Thanks for taking the time to reply.
If you want to be able to count instance hits, have a look at the shared memory option here.[^]
This article also shows some other techniques which I think fix some of the problems described in Joe Newcomer's article first referenced above. I have used the shared memory technique to inhibit multiple instances of a program as well as manage some common data in a program where I allow multiple instances.
[I have a lot of respect for the technical output of both of these authors.]
Visual Studio 2008, Windows 7
I create the basic MFP application with Single or Multiple documents, then immediately compile and run it. Using the File -> Open option I can navigate to and open a file.
However, when looking through the code I do not recognize any variable that might be the handle to a file. How do I acces that file I just opened?
It's a while since I used MFC but I think the actual handle is held internally by the CDocument object. When you open the file the framework should call your OpenFile() method (I think that's its name) and you then load the data from the file using the CArchive object. The skeleton code should be there in your document class.
One of these days I'm going to think of a really clever signature.