Advertisement

asynchronous callback based sockets in unmanaged c++

Started by August 01, 2005 11:57 AM
6 comments, last by Tim Cowley 19 years, 6 months ago
I have succeeded in creating a robust server client system using asynchronous sockets in c#. I think the method of setting callbacks to respond to connect, accept, and receive events is only sensible and extremely elegant. However, since my clients will be coded in unmanaged c++ I cannot just directly use this real nice c# system. When searching through the winsock APIs for unmanaged c++ I did not notice a callback system anywhere which was dissapointing. I was wondering if there is one in the first place, and if not would calling c# client code from my unmanaged app be easy or should I just plan on using standard winsock?
I prefer and recommend winsock. However, since you mentioned that the C# socket component is solid, then check out COM.

Kuphryn
Advertisement
I believe you can expose an unmanaged API from a managed assembly by using unmanaged C++ and exporting __nogc objects -- but that's really a question for the tool crowd, not for the network programming crowd.

When it comes to callback interfaces, WinSock has various modes of operation, including IO completion ports, async select (which posts messages), and plain select() polling.

If you want to express the concept of a delegate (which I believe is what you're talking about when you say "callbacks") in C++, usually a good primitive is the abstract interface. I e, you declare something like:

class ISocketUser {public:  virtual void onAccept( ISocket * newSocket ) = 0;  virtual void onReceive( data etc ) = 0;  ...};


Your application code implements this interface and hands it to your socket library, which uses it to call back to the application when it needs to.

Again, this is much more of a software engineering question than a networking question, so you're likely to find better answers in a forum dedicated to the languages/environments you're using.
enum Bool { True, False, FileNotFound };
It seems like asynchronous sockets in unmanaged c++ will be the closest to what I'm looking for. Unfortunately it seems that including both windows.h and winsock2.h introduces some serious declaration reclarations, anyone experience this?
You must include <winsock2.h> before you include <windows.h>. I thought this was mentioned in the Forum FAQ -- but maybe not.
enum Bool { True, False, FileNotFound };
Quote:
Original post by hplus0603
You must include <winsock2.h> before you include <windows.h>. I thought this was mentioned in the Forum FAQ -- but maybe not.


I do not see it there, but I apologize if I missed it, if not then that's an important addition to the faq I think.
Advertisement
This is a skeleton console based asynchronous client in unmanaged c++ I am trying to develop. It however merely manages to connect to my server but doesn't output "connection was established \n" as the program indicates it should (the only way I can tell it connects is because my server tracks it as a client).
Also it doesn't output any messages it receives. However any data I send does get received by the server. In short it seems my switch case system is not working.


#include <iostream>#include <winsock2.h>#include <windows.h>using namespace std;extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();int main(){	////initializing WinSock API....	WSADATA WsaDat;	if( WSAStartup( 2.2 , &WsaDat ) != 0 )		cout<<"could not initialize winsock"<<endl;		////making remoteSocket a stream tcp type	SOCKET connection = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );   	if ( connection == INVALID_SOCKET )		cout<<"could not create stream socket"<<endl;	//make it asynchronous	WSAAsyncSelect(connection, GetConsoleWindow(), 5986, FD_WRITE | FD_CONNECT |  FD_READ | FD_CLOSE);	//process data needed to connect to remote host	SOCKADDR_IN saRemote;	LPHOSTENT lpHostEntry;	char buffer[100];	lpHostEntry = gethostbyname( "127.0.0.1" );	if (lpHostEntry == NULL)		cout<<"could not find host"<<endl;			saRemote.sin_family = AF_INET;	saRemote.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);									saRemote.sin_port = htons( 20000 );		//connect to server...	connect(connection, (LPSOCKADDR)&saRemote, sizeof(struct sockaddr));		//main network message handling loop	while( 1 )	{		long networkEvents = 5986;		WSAEventSelect( connection, GetConsoleWindow(), networkEvents );		switch( networkEvents )		{			case FD_READ:					recv( connection, buffer, 40, 0 );					cout << buffer;					break;			case FD_WRITE:					break;			case FD_CONNECT:					cout << "connection was established \n";					break;			case FD_CLOSE:				    break;		}	}	return 0;}


I notice this program is an infinite loop, this is just temporary for testing purposes since I can easily force close the app.
Quote:
Original post by Khaos Dragon
This is a skeleton console based asynchronous client in unmanaged c++ I am trying to develop. It however merely manages to connect to my server but doesn't output "connection was established \n" as the program indicates it should (the only way I can tell it connects is because my server tracks it as a client).
Also it doesn't output any messages it receives. However any data I send does get received by the server. In short it seems my switch case system is not working.


*** Source Snippet Removed ***

I notice this program is an infinite loop, this is just temporary for testing purposes since I can easily force close the app.

You're:

a) Selecting each iteration; questionable at best :p
b) Passing GetConsoleWindow() as the event parameter to WSAEventSelect. Is this intentional/just a stub?
c) Switching networkEvents, which is never touched by Winsock.

I'd say c) is your actual problem, but I recommend you look into the others too.

This topic is closed to new replies.

Advertisement