• Welcome to Valhalla Legends Archive.
 

[C++] Questions

Started by Sorc.Polgara, November 17, 2004, 03:22 PM

Previous topic - Next topic

Eibro

Speaking from experience, the easiest (or as Kp put it, most convenient) way to deal with async sockets is overlapped I/O. Specifically, overlapped completion routines. If you're building a server application you may want to go with overlapped completion ports.

If you want a minimal example of how to use completion routines, see http://cs.smu.ca/~e_brooks/overlapped.cpp
Eibro of Yeti Lovers.

OnlyMeat

MyndFyre i suggest you stick to your interpreted languages as you clearly dont understand c++.

Quote from: MyndFyre on November 17, 2004, 06:50 PM
Quote from: bethra on November 17, 2004, 03:22 PM
1.  Does VC++ Winsock v2 have Events, separate functions that are triggered when ___ happens lik in VB6 Winsock?  If so, can I get a simple example of using a VC++ Winsock Event?  I could not find anything in the MSDN Library or the C++ Winsock Tutorials to help.
What you'll find is that you'll have to get function pointer callbacks yourself to pass for functions, not like in VB.

That is complete non-sense you dont need function pointers to use winsock, the easiest way would be to use windows messaging.

Use WSAAsyncSelect to first select which winsock events you wish to be notified about i.e FD_READ. Then just call the standard berkley implementation functions i.e recv(). This will then call your main winproc message handling function with your custom message that you passed to WSAAsyncSelect.

Another way would be to use WSAEventSelect which is more suitable for UI less applications and possibly if you wish to handle events using additional threads.

WSAEventSelect  works by using kernel events in conjunction with WSAWaitForMultipleEvents and WSAEnumNetworkEvents, generally you would fire off a separate thread polling the WSAWaitForMultipleEvents API function which enters an efficient wait state until the timeout elapses. Then you handle the specific event and possibly notify your main thread.

Quote from: MyndFyre on November 17, 2004, 06:50 PM
Quote from: bethra on November 17, 2004, 03:22 PM
3.  When converting a null-terminating string to a non-null-terminating string, is this an efficient way of doing so?

strncpy(strDest, strSrc, strlen(strSrc) - 1)

Most every use for non-null-terminating strings in Battle.net communication are those four-byte DWORDs.  You can define them instead as:

// assumed typedef long int DWORD;
DWORD myProductId = 'STAR';

Note the single quotes.

That declaration is not required you can store them in char consts and simply call


memcpy( szDestBuf+nBufOffset,szSourceBuf,strlen(szSourceBuf) );


When you need to copy it to your winsock outgoing buffer (Packet).

Note strlen provides the actual string byte sequence length minus the trailing terminator.

Quote from: MyndFyre on November 17, 2004, 06:50 PM
Quote from: bethra on November 17, 2004, 03:22 PM
4.  Should I avoid using Windows API or MFC classes if I don't plan to use a Windows GUI, but a command line interface?
You don't need to avoid the API unless you want to be able to compile it cross-platform.  As for MFC, if you want your bot to be bloated and contain loads of meaningless nothings, don't use it.

The windows API has it's uses, but it can be tedious and most times you end up writing wrapper classes to implement common functionality across multiple applications.

This is where the MFC library helps out, i use it quite often it saves alot of time, in someways it simplifies programming in c++ like a 4th generation language. The people who say it's bloated like mindfyre probably have never even used it and simply jump on the purist bandwagon because other people say thats the way it is. I can tell you now MFC is very usefull it outperforms java .net  dephi vb 6.0 etc thats why the actually c++ environment is written using MFC. And thats not really an issue anyways because like i said it simply saves you from having to write API wrapper classes anyways.

The wrappers are usually quite light and provide a good infrastructure, of course you dont need to make your application pure MFC it can mix and match the best features from any of the supporting frameworks depending on your goals - STL ATL MFC etc.

MFC really comes into it's own with it's windows message routing system which makes handling/overloading windows events incredibly simplistic. The UI support is MFC's more powerfull feature so if you dont use a UI then you have to weigh up the other cons/pros of using it, like i said it's just a framework and it wont be suitable for all scenarios and like every framework or language it's not perfect so dont pay any attention to these sheep who jump on the bandwagon and try it yourself and make your own decision.

Note CString class in MFC is just like programming in vb with strings really if that helps.

Quote from: MyndFyre on November 17, 2004, 06:50 PM
Quote from: bethra on November 17, 2004, 03:22 PM
5.  What is the most efficient way of creating a dynamic string/array?
This would be a question better suited to others.  :)  Sorry.

You should have applied that same logic to all your answers myndfyre.

In pure c++ to create a dynamic char ( string ) array  you could do this:-


char* pszBuf = new char[1024];


Where the new operator allocates a character array of 1024 bytes. Any structure, class, primative//defined type can be allocated this way.

You could then initialize the buffer with a string value.


memset( pszBuf ,0,1024);
memcpy( pszBuf ,szMyString, strlen(szMyString));


And to deallocate the memory you call the delete operator.


delete [] pszBuf;


Note the [] tells the delete operator that the memory is an array, this is important to ensure the memory is cleaned up properly.

You can use the c runtime library allocation functions ( malloc//free ) as well instead of the c++ specific new operator but in debug mode ( and release if configured correctly ) the new operator can track memory allocations etc which makes it easier to find memory leaks.

MyndFyre

Quote from: OnlyMeat on November 20, 2004, 12:37 AM
MyndFyre i suggest you stick to your interpreted languages as you clearly dont understand c++.
Wow.  Way to go flamer.  Not only did two respected vL members post after me and not argue with anything that I'd said, but then you also specifically called me out when I have done nothing to deserve it. 

Quote from: OnlyMeat on November 20, 2004, 12:37 AM
That is complete non-sense you dont need function pointers to use winsock, the easiest way would be to use windows messaging.

Use WSAAsyncSelect to first select which winsock events you wish to be notified about i.e FD_READ. Then just call the standard berkley implementation functions i.e recv(). This will then call your main winproc message handling function with your custom message that you passed to WSAAsyncSelect.

Another way would be to use WSAEventSelect which is more suitable for UI less applications and possibly if you wish to handle events using additional threads.

WSAEventSelect  works by using kernel events in conjunction with WSAWaitForMultipleEvents and WSAEnumNetworkEvents, generally you would fire off a separate thread polling the WSAWaitForMultipleEvents API function which enters an efficient wait state until the timeout elapses. Then you handle the specific event and possibly notify your main thread.
Note that he asked for events.  The only way to generate any kind of event-style methodology in C programming similar to VB is to use a callback at one level or another.  Even if you're looking at messages, guess what -- your message loop is a callback!  That's beside the point anyway. 

Quote from: OnlyMeat on November 20, 2004, 12:37 AM
That declaration is not required you can store them in char consts and simply call

memcpy( szDestBuf+nBufOffset,szSourceBuf,strlen(szSourceBuf) );

When you need to copy it to your winsock outgoing buffer (Packet).
Why would you do that?  Why incur a memory-copying operation when you can just use them as integral constants?  Let's say you have a four-character string; the C compiler will generate a 5-byte result (4 characters plus NULL), and pad an extra 3 NULLs for proper offset, for a total usage of twice the memory.  Then you have to incur a memory copying operation to use them for their intended purpose, where it would just be easier to use a constant anyway.

Quote from: OnlyMeat on November 20, 2004, 12:37 AM
The windows API has it's uses, but it can be tedious and most times you end up writing wrapper classes to implement common functionality across multiple applications.

This is where the MFC library helps out, i use it quite often it saves alot of time, in someways it simplifies programming in c++ like a 4th generation language. The people who say it's bloated like mindfyre probably have never even used it and simply jump on the purist bandwagon because other people say thats the way it is. I can tell you now MFC is very usefull it outperforms java .net  dephi vb 6.0 etc thats why the actually c++ environment is written using MFC. And thats not really an issue anyways because like i said it simply saves you from having to write API wrapper classes anyways.

The wrappers are usually quite light and provide a good infrastructure, of course you dont need to make your application pure MFC it can mix and match the best features from any of the supporting frameworks depending on your goals - STL ATL MFC etc.

MFC really comes into it's own with it's windows message routing system which makes handling/overloading windows events incredibly simplistic. The UI support is MFC's more powerfull feature so if you dont use a UI then you have to weigh up the other cons/pros of using it, like i said it's just a framework and it wont be suitable for all scenarios and like every framework or language it's not perfect so dont pay any attention to these sheep who jump on the bandwagon and try it yourself and make your own decision.

Note CString class in MFC is just like programming in vb with strings really if that helps.
I like the object-oriented features of MFC.  But in comparing MFC to the Windows API, I've found that in most cases, MFC objects contain member methods that mirror those of the Windows API with one or two parameters difference.  CString is obviously a very handly utility class, but if that or even a couple other classes are all you end up using from MFC, is it really worth linking in the entire MFC library?

Quote from: OnlyMeat on November 20, 2004, 12:37 AM
You should have applied that same logic to all your answers myndfyre.
Way to flame, retard.

Quote from: OnlyMeat on November 20, 2004, 12:37 AM
In pure c++ to create a dynamic char ( string ) array  you could do this:-


char* pszBuf = new char[1024];


Where the new operator allocates a character array of 1024 bytes. Any structure, class, primative//defined type can be allocated this way.
Why 1024?  What if you know your strings are never going to exceed, say, 256 bytes in length?  Is there a reason you chose an arbitrarily large number?
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

OnlyMeat

#18
Quote from: MyndFyre on November 20, 2004, 02:55 AM
Quote from: OnlyMeat on November 20, 2004, 12:37 AM
That is complete non-sense you dont need function pointers to use winsock, the easiest way would be to use windows messaging.

Use WSAAsyncSelect to first select which winsock events you wish to be notified about i.e FD_READ. Then just call the standard berkley implementation functions i.e recv(). This will then call your main winproc message handling function with your custom message that you passed to WSAAsyncSelect.

Another way would be to use WSAEventSelect which is more suitable for UI less applications and possibly if you wish to handle events using additional threads.

WSAEventSelect  works by using kernel events in conjunction with WSAWaitForMultipleEvents and WSAEnumNetworkEvents, generally you would fire off a separate thread polling the WSAWaitForMultipleEvents API function which enters an efficient wait state until the timeout elapses. Then you handle the specific event and possibly notify your main thread.
Note that he asked for events.  The only way to generate any kind of event-style methodology in C programming similar to VB is to use a callback at one level or another.  Even if you're looking at messages, guess what -- your message loop is a callback!  That's beside the point anyway. 

First of all he asked about winsock events which have specific ways of calling back into an application none of which include manually passing pointers to functions.

Second there are other ways of generating vb style events in c++ apart from manually passing pointers to functions. Polymorphism and COM interfaces can be used to implement this without the need to specificially pass function pointers in your application. Of course anyone who knows about the implementation of polymorphism in c++ knows it uses virtual function pointers but this is intrinsic to c++ and does not require any manual coding.

Also to note you cant use function pointers manually to call into multiple instances of a class unless it's a static ( which means it cant use member data ) or it;s a singleton, in any case it's not the best way to do it which again proves your knowlege on the subject is limited ( im not flaming im pointing out facts if you dont like it then dont print false comments ) .

Quote from: MyndFyre on November 20, 2004, 02:55 AM
Quote from: OnlyMeat on November 20, 2004, 12:37 AM
That declaration is not required you can store them in char consts and simply call

memcpy( szDestBuf+nBufOffset,szSourceBuf,strlen(szSourceBuf) );

When you need to copy it to your winsock outgoing buffer (Packet).
Why would you do that?  Why incur a memory-copying operation when you can just use them as integral constants?  Let's say you have a four-character string; the C compiler will generate a 5-byte result (4 characters plus NULL), and pad an extra 3 NULLs for proper offset, for a total usage of twice the memory.  Then you have to incur a memory copying operation to use them for their intended purpose, where it would just be easier to use a constant anyway.

If you actually read what i said then you would see that the example code was for copying to the packet buffer, which is required unless you have another way of copying a string to the packet buffer without calling memcpy?, Read first then write a response please.

Quote from: MyndFyre on November 20, 2004, 02:55 AM
I like the object-oriented features of MFC.  But in comparing MFC to the Windows API, I've found that in most cases, MFC objects contain member methods that mirror those of the Windows API with one or two parameters difference.  CString is obviously a very handly utility class, but if that or even a couple other classes are all you end up using from MFC, is it really worth linking in the entire MFC library?

Firstly no one can compare MFC to the API because it's not the same thing for a start, MFC is a framework to be used in conjunction with the MS C++ implementation and the API is the offical operating system programming interface.

Secondly do you know what a wrapper is?, a wrapper is usually a thin implementation that simplifies the programming interface and thats exactly what MFC does. It provides simplified object orientated and uniform interfaces to the windows API.

If you had actually used MFC which i highly doubt you have past the use of CString then you would know it has many helper classes/wrappers that include:-

(1) Generic object serialization.
(2) Doc/view paradigm ( which is extremely powerfull and object orientated )

(3) Control subclassing
(4) Very simplistic File IO classes which implement some nice features.

And many more, really to many to mention and just proves that you have used little or none of it and are therefore not qualified to judge it.

Quote from: MyndFyre on November 20, 2004, 02:55 AM
Quote from: OnlyMeat on November 20, 2004, 12:37 AM
In pure c++ to create a dynamic char ( string ) array  you could do this:-


char* pszBuf = new char[1024];


Why 1024?  What if you know your strings are never going to exceed, say, 256 bytes in length?  Is there a reason you chose an arbitrarily large number?

You are really clutching at straws are'nt you 1024 has no meaning it's called an example.

In pure c++ to create a dynamic char ( string ) array  you could do this:-

Another reason you dont understand c++, a char array in c++ is the same as a byte array except that it's signed therefore it can be used to contain not only ascii codes but other data. An example for a large buffer would be a winsock packet buffer for incoming data ( for example in game d2 clients receive amounts of data greater than 256 bytes which must be stored in a buffer. Also there is no limit on string lengths in c++, you can have a 10,000 byte char array if you so wish.

Arta

WSAAsyncSelect isn't very nice. IIRC it just creates a thread which waits on the socket and then SendMessage()s you. It's also completely unsuitable for many server applocations, which run as services. Either way, it's an extra thread for no good reason.

Overlapped IO is really quite nice: have you ever used it?

OnlyMeat

Quote from: Arta[vL] on November 20, 2004, 09:03 AM
WSAAsyncSelect isn't very nice. IIRC it just creates a thread which waits on the socket and then SendMessage()s you. It's also completely unsuitable for many server applocations, which run as services. Either way, it's an extra thread for no good reason.

Overlapped IO is really quite nice: have you ever used it?

I Agree WSAAsyncSelect  is quick and dirty, completely unsuitable for server apps. I think for a single connection bot it might be ok though or a simple client http app of some sort.

I have'nt done a full implementation of overlapped IO in a project as of yet, but it does look interesting hopefully i will get a chance to try it properly soon, Iv heard alot about the scalability of it whats your take on that?

Sorc.Polgara

#21
Quote from: Eibro[yL] on November 20, 2004, 12:29 AM
Speaking from experience, the easiest (or as Kp put it, most convenient) way to deal with async sockets is overlapped I/O. Specifically, overlapped completion routines. If you're building a server application you may want to go with overlapped completion ports.

If you want a minimal example of how to use completion routines, see http://cs.smu.ca/~e_brooks/overlapped.cpp

Nice!  Although I copied the .cpp file and can't compile it.  I believe it has to with the library that assert() uses.  I've tried linking the libraries that MSDN Library says to use link for assert() but it doesn't seem to want to compile.
Quote
Libraries

LIBC.LIB Single thread static library, retail version
LIBCMT.LIB Multithread static library, retail version
MSVCRT.LIB Import library for MSVCRT.DLL, retail version

I tried linking each one by the Project\Settings\Link menu and it doesn't work.
I've also tried to use a pragma. No luck

that source looks awesome, I want to see if I can compile/run it and then make my own.


Damn, flaming = nothx
help + love = thxly

Zakath

You can remove the asserts. All assert does is kill the running program if the condition that follows it is false. You can use an if/else to exit(0) if you want to simulate that.
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

Eibro

You can complile/link it on the VC++ command line by doing the following:

cl overlapped.cpp
link overlapped.obj user32

Then to run it just type

overlapped

You can typically get to the VC++ command prompt by following Start->Programs->VC->Tools->VC Command Prompt

Eibro of Yeti Lovers.

Arta

Quote from: OnlyMeat on November 20, 2004, 09:35 AM
I Agree WSAAsyncSelect  is quick and dirty, completely unsuitable for server apps. I think for a single connection bot it might be ok though or a simple client http app of some sort.

I have'nt done a full implementation of overlapped IO in a project as of yet, but it does look interesting hopefully i will get a chance to try it properly soon, Iv heard alot about the scalability of it whats your take on that?

Good, although apparently not as good as using IO completion ports. I've not read much about that yet though. I've been using a combination of WSAEventSelect and APCs.

Mephisto

Quote from: Kp on November 19, 2004, 11:58 PM
Quote from: Mephisto on November 19, 2004, 06:07 PMAlso WSARecv & WSASend & WSABUF structure.

HANDLE SocketEvent = CreateEvent(0, 0, 0, 0); // the parameters are generally not necessary in most cases
WSAEventSelect(YourSocket, SocketEvent, FD_CONNECT|FD_CLOSE); // you can look up the flags in the last parameter on MSDN
You now have a socket event bound to your socket.  You can use it how you need to

No, don't look at those.  Using those isn't as efficient or convenient as overlapped I/O.

Isn't it overlapped I/O if you use an OVERLAPPED structure and CALLBACK procedure for a Recv complete and a Send complete?  I know it's ano an I/O completion port, but it's overlapped I/O, unless I'm mistaken.

Zakath

You are correct. Overlapped i/o is not necessarily the same thing as i/o completion ports. Such ports are one way of achieving overlapped i/o.
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

Mephisto

Thank you for clarifying.  Additionally, overlapped I/O ports are better used for a server application than a client application, yes?

Sorc.Polgara

Quote from: Eibro[yL] on November 20, 2004, 01:20 PM
You can complile/link it on the VC++ command line by doing the following:

cl overlapped.cpp
link overlapped.obj user32

Then to run it just type

overlapped

You can typically get to the VC++ command prompt by following Start->Programs->VC->Tools->VC Command Prompt

Sorry, but I don't understand this.  I've have tried, but I must be doing something wrong.

VC Command Prompt? wtf?  I don't have w/e that is.  I'm using VC6++ so...

Skywing

Quote from: Mephisto on November 20, 2004, 06:00 PM
Thank you for clarifying.  Additionally, overlapped I/O ports are better used for a server application than a client application, yes?
I use them for both.  It requires you to split network processing and UI/windows message processing into seperate threads, but this isn't such a bad idea as it stands because network operations don't have to wait on slow UI operations to complete like they would if you did both in the same thread.

|