networking dll of sandman for bennu

Started by DCelso, August 20, 2008, 07:12:42 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Windgate

Hi Sandman,
I have chequed it, and net_init returns 65538 always, even if network switch is off :P

Ok, i will try it, check your forum mail box, I send you my instant message contact

Thanks for the consolereports tip and karma++
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Sandman

Woops, didn't see your post, was on second page, hehe. Well error found anyway and documentation fixed.

Let me know how it's going.  :)
-- Sandman

Windgate

Hi Sandman, bad news :S

I'm trying to write a VERY VERY VERY simple client server program. Server just send "HOLA" to client on local host at every FRAME and client just listen and say what it receives from the server.

Server run first and always say connection 0 invalid, and client shows an empty string...

Here the full code, it is very simple:

QuoteIMPORT "mod_key";
IMPORT "mod_grproc";
IMPORT "mod_string";
IMPORT "mod_text";
IMPORT "mod_say";

INCLUDE "libnetwork.inc";

CONST
   _SERVER_IP = "192.168.0.11";
   _SERVER_PORT = 6112;
END

GLOBAL
   //
END

PROCESS main ( )
PRIVATE
    init_status;
BEGIN

   NET.ConsoleReports = TRUE;
   init_status = net_init ( 0 , 10 , 1 );   // It always returns 65538, can't check errors by now

    menu ( );
   
    REPEAT
        FRAME;
    UNTIL ( key ( _ESC ) );

    // Disconnect and quit.
    net_quit ( );
    let_me_alone ( );

END

FUNCTION menu ( )
BEGIN
   write ( 0 , 0 , 0 , 0 , "Key 1 for server" );
   write ( 0 , 0 , 10 , 0 , "Key 2 for client" );
   LOOP
      IF ( key ( _1 ) ) server ( ); BREAK; END
      IF ( key ( _2 ) ) client ( ); BREAK; END
      FRAME;
   END
END

PROCESS server ( )
PRIVATE
   int connection = 0;
BEGIN
   connection = net_listen ( _SERVER_PORT , TRUE );
   LOOP
      net_message ( connection , "HOLA" );
      FRAME;
   END
END

PROCESS client ( )
PRIVATE
   int connection;
   string message;
BEGIN
   connection = net_connect ( _SERVER_IP , _SERVER_PORT , TRUE );
   LOOP
      message = net_getmessage ( connection );
      say ( message );
      FRAME;
   END
END
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Sandman

Correct. You are trying to send a message to a listening port, but this is not a valid connection. When the client connects to the server, the server will create a new connection for that client.

So what you need to do in the server:
- open listening port (like you do)
- wait for client and a NEW connection
- send messages to client

I'm unsure about how the waiting part is best done. Hm I didn't make this part easy enough. What you can do is:

PROCESS server ( )
PRIVATE
   int connection = 0;
BEGIN
   connection = net_listen ( _SERVER_PORT , TRUE );
Loop
    switch(NET.Incoming[1])
        case NET_STATUS_ESTABLISHED:
            // code when the connection is just established
            say("# Connected!");
            break;
        end
    end
    frame;
End

   LOOP
      net_message ( 1 , "HOLA" );
      FRAME;
   END
END

But this is an incredibly ugly hack. I didn't think about this enough. I will make it better.
-- Sandman

Sandman

I added two new functions:
* NET_Incoming_Accept
* NET_Accept

In your program you can use them like this:

IMPORT "mod_key";
IMPORT "mod_grproc";
IMPORT "mod_string";
IMPORT "mod_text";
IMPORT "mod_say";

INCLUDE "libnetwork.inc";

CONST
  _SERVER_IP = "localhost";
  _SERVER_PORT = 6112;
END

GLOBAL
  //
END

PROCESS main ( )
PRIVATE
   init_status;
BEGIN

  NET.ConsoleReports = TRUE;
  init_status = net_init ( 0 , 10 , 1 );   // It always returns 65538, can't check errors by now

   menu ( );
 
   REPEAT
       FRAME;
   UNTIL ( key ( _ESC ) );

   // Disconnect and quit.
   net_quit ( );
   let_me_alone ( );

END

FUNCTION menu ( )
BEGIN
  write ( 0 , 0 , 0 , 0 , "Key 1 for server" );
  write ( 0 , 0 , 10 , 0 , "Key 2 for client" );
  LOOP
     IF ( key ( _1 ) ) server ( ); BREAK; END
     IF ( key ( _2 ) ) client ( ); BREAK; END
     FRAME;
  END
END

PROCESS server ( )
PRIVATE
  int listen_connection = -1;
  int connection = -1;
BEGIN
listen_connection = net_listen ( _SERVER_PORT , TRUE );

/* Method 1*/
// Loop
// say(NET.Incoming[listen_connection]);
//    switch(NET.Incoming[listen_connection])
//        case NET_STATUS_ESTABLISHED:
//            // code when the connection is just established
//            say("# Connected!");
//            connection = net_incoming_accept(listen_connection);
//            break;
//        end
//    end
//    frame;
// End

/* Method 2*/
connection = net_accept(listen_connection);

// etc

LOOP
net_message ( connection , "HOLA" );
FRAME;
END
END

PROCESS client ( )
PRIVATE
  int connection;
  string message;
BEGIN
  connection = net_connect ( _SERVER_IP , _SERVER_PORT , TRUE );
  LOOP
     message = net_getmessage ( connection );
     say ( message );
     FRAME;
  END
END


It took some effort to remain backwards compatible, but at least in this example it works properly. Hope this of more use to you.
-- Sandman

Windgate

I'll check it in a while, thanks an other karma up xD
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

Well, "little" bad news...

I have tried your new functions now, but I have an error:

Undefined procedure: NET_ACCEPT

I suposse that function is added on the new version, but I have downloaded from the Wiki the libnetwork.dll v1.57 Win32 for Bennu and its the same version of the dll I had... Where can I find the new version you made? I have taken a look on boolean soup and can't find it... :'(

Help...
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

Here is a very first functional version of simple communication client/server:

http://trinit.es/DescargaDirecta/BennuDLL/NetworkTest/Windgate's%20Network%20Test%200.0.1.zip

Next step: Two remote clients moving on screen...
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

Well, here is a very stupid version of a 2 players game, the server is a player and the client is the other player, and it is possible to move players using keys. You can change the IP at /prg/const.prg, the current IP is my own IP :P

DOWNLOAD: http://trinit.es/DescargaDirecta/BennuDLL/NetworkTest/Windgate's%20Network%20Test%200.0.1b.zip

PD: On remote connection remember that you must open 6112 port, or change it at /prg/const.prg
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

I tried to build the network.dll using CodeBlocks, Sandman helps me a fucking lot with this, I had to download all Bennu source and some SDL files... Im not used to do this weird things, so I have make a CodeBlocks projects with ALL, ready to build and go.

Anyone wants to try it?

DOWNLOAD: http://trinit.es/DescargaDirecta/BennuOthers/DLL%20build%20sample.zip

:P
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Sandman

Now a Linux version available at the great wiki.

Your project works here, but that could also be because I've got a global setup. But, the dependencies are there (except libbgdrtm).
-- Sandman

Drumpi

Quote from: Windgate on December 03, 2009, 01:12:40 PM
I tried to build the network.dll using CodeBlocks, Sandman helps me a fucking lot with this, I had to download all Bennu source and some SDL files... Im not used to do this weird things, so I have make a CodeBlocks projects with ALL, ready to build and go.

Anyone wants to try it?

DOWNLOAD: http://trinit.es/DescargaDirecta/BennuOthers/DLL%20build%20sample.zip

:P

Hey, i will take a look to this. It's very interesting and i will need it (but now i'm REALLY busy to test, sorry).
Jusk karma up to both of you.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Windgate

Sandman, I have take off the global setup :P

My next step: Compile any dlls of Bennu

But I want to make playable my network test first, maybe in 3D xD
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

#28
Bad news, I'm working on a protocol which can allow the server to accept many connected clients.

The protocol is not functional yet, but I have a first error when I listen again to accept a new client when the first one is connected:

GLOBAL
int connections [ _MAX_CLIENTS ];
int connected_clients = 0;
END

PROCESS accept ( )
PRIVATE
int listen_connection [ _MAX_CLIENTS ];
BEGIN
write ( 0 , 0 , 0 , 0 , "Connected clients: " );
write_var ( 0 , 120 , 0 , 0 , connected_clients );
LOOP
listen_connection [ connected_clients ] = net_listen ( _SERVER_PORT , TRUE );
connections [ connected_clients ] = net_accept ( listen_connection [ connected_clients ] );
connected_clients++;
FRAME;
END
END


I get an error on the server program when the first client connects and the accept() process tries to listen again:

"Error, could not listen on connection"

S.O.S dear Mr. Sandman :(
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Sandman

#29
You only tell the dll once that you want to listen on a port, not multiple times. It will allow multiple clients to connect. If you want to stop listening, use net_disconnect() on the listening connection. So just move that line outside of the loop and you're done.

EDIT: codes
GLOBAL
int connections [ _MAX_CLIENTS ];
int connected_clients = 0;
END

PROCESS accept ( )
PRIVATE
int listen_connection;
BEGIN
write ( 0 , 0 , 0 , 0 , "Connected clients: " );
write_var ( 0 , 120 , 0 , 0 , connected_clients );
listen_connection = net_listen ( _SERVER_PORT , TRUE );
LOOP
connections [ connected_clients ] = net_accept ( listen_connection );
connected_clients++;
FRAME;
END
ONEXIT
net_disconnect( listen_connection ); // NOTE: this will NOT disconnect all the clients...
END
-- Sandman