Jump to content

Help with the SOCKET Library


Guest Booksized

Recommended Posts

Hello everyone I need some help :)

I'm actually try to design a ServicePort for the Mangos Cores.

The Listerner (Server) is the Realmmanager, actually with telnet (for debug)...

I had implementet an second Socket, in the realmd, build in a minidialog between an old TrinityCore and Mangos Realmd.

It works fine, the systems are Talking and they could exchange their data.

Now I've build in an dynamic CoreMap, thats the struct for the Cores, the role from the Core (like sub cores) and it's socket_IDs (for crossover transfer).

Its organized like the realmmap (and its working great, at my first construcions i has used the socket_ID :lol: )

But now i have a big problem, i can't change the active remote socket number, like:

CORE1: SOCKET_ID 336

CORE2: SOCKET_ID 388

SEND 336 to 388

I've programmed a reference contruct in VB and it works great there, but i have no Idea how does it works in C++ ... :confused:

All others works, but not switching the active sockets -.-

If anyone have an idea, pleeze write it down :)

Greez GiR-Zippo-Booksized

The reason for building this port is to connect come cores, without direct acces to the database from the Core1 to Core 2 (like syncronising some Quests or globalannounces for all cores, Bots, ...) , so i can connect Server1:Core1+2 and Server2:Core1+2, so the Cores may have an RealmdPoolmaster and a normal Realmd.

Link to comment
Share on other sites

Okay, i think i've wrote it tooooooooo complicated.

My problem is the following:

If Core1 connects to the realmport and sending some commands to Core2, the realmd should change the active socket-session-number to the right one from Core2.

Like Core1 -send to> Core2.

Both Cores loged in as Client and they are sending, the clients(cores) stayed loged in and the connections weren't closed until the server is shutting down.

Thats the Handler for setting the connection_ ID's...


void CSYHandler::SetServerID(uint32 socketID, const char * ServerName) 
{
       ServerMap& servermap = m_scmap[serverName];
       servermap.server_ID = socketID;
       servermap.servername = ServerName;
       sLog.outString ("CSY: STORED %d : %s in the CoreMap\\n", socketID, servermap.servername.c_str ());
}

...

Thats in the mainroutine for firing up the listenPort:
I've added it in the main.cpp under the AuthSocket (thats the best place i thought) 

///- Launch the Service network socket
   port_t csport = sConfig.GetIntDefault( "CSYPort", DEFAULT_CASSY_PORT );
   std::string csbind_ip = sConfig.GetStringDefault("CSYBindIP", "0.0.0.0");

   SocketHandler p;

   ListenSocket<Cassy> CassyListenSocket(p);
   if ( CassyListenSocket.Bind (csbind_ip.c_str(),csport))
   {
       sLog.outError( "Cassy can not bind to %s:%d",csbind_ip.c_str(), csport );
       return 1;
   }
   sLog.outString ("CSY: Startet on %s : %d\\n",csbind_ip.c_str(),csport);
   p.Add(&CassyListenSocket);

...

/// The Main Routine  It's an modded RaConsole
void Cassy::OnRead()
{
   TcpSocket::OnRead();
   unsigned int sz=ibuf.GetLength();
   if(iInputLength+sz>=RA_BUFF_SIZE)
   {
       sLog.outRALog("Input buffer overflow, possible DOS attack.\\n");
       SetCloseAndDelete();
       return;
   }
   char *inp = new char [sz+1];
   ibuf.Read(inp,sz);

   /// \\todo Can somebody explain this 'Linux bugfix'?
  /* if(stage==MAIN)
       if(sz>4)                                            //linux remote telnet
           if(memcmp(inp ,"USER ",5))
           {
              delete [] inp;return;
               printf("lin bugfix");
           }                                               //linux bugfix
   */
   ///- Discard data after line break or line feed
   bool gotenter=false;
   unsigned int y=0;
   for(;y<sz;y++)
       if(inp[y]=='\\r'||inp[y]=='\\n')
   {
       gotenter=true;
       break;
   }

   //No buffer overflow (checked above)
   memcpy(&buff[iInputLength],inp,y);
   iInputLength+=y;
   delete [] inp;
   if(gotenter)
   {

       buff[iInputLength]=0;
       iInputLength=0;
       sLog.outString ("CSY: %s\\n",buff);    
       uint32 sessionID=GetSocket();
       switch(stage)
       {

           // Please note, this is the main login routine, every core have to check (denk drann du brauchst ne zweite Datenbank zum gegencheck, danke  )
           case LOGIN:

               if(!memcmp(buff,"I am ",5)) 
               {
                   std::string ss=GetRemoteAddress();
                   corename=&buff[5];
                   Sendf ("Welcome %s:%s\\r\\n",ss.c_str(), corename.c_str());
                   csyhandler.SetServerID (sessionID, corename.c_str());
                   stage=MAIN;
               }

           break;                        

           case MAIN:
               if(!memcmp(buff,"I've got a command for ",23)) 
               {
                   corename=&buff[23];
                   if (!memcmp(corename.c_str(),"you",3))
                   {    
                       stage=CMD;
                       break;
                   }
                   csyhandler.SetListenClient(sessionID, corename.c_str ());
                   stage=ROUTE;

               }
           break;

           /***************************************************/
           /*** Handle the SubCommands for the Realmmanager ***/
           /***************************************************/
           case CMD:
               sLog.outString("CSY:Command in process...\\n");
               if(!memcmp(buff,"Get Ping.",9))
               {
                   PingBack();
                   stage=MAIN;
               }
...

I hope now someone can help me now :huh:

Otherwise I have to write the PoolManager in VB6 (it would take one hour), than the whole system would work without any service port at the realmd. And without any Linux support (sry).

But this port is essentially for my CoreSystem, cause it'll the mastersystem for syncing my cores... :cool:

Greetz GiR-Booksized

Link to comment
Share on other sites

From what I can say - I probably didn't get your idea. What do you call a 'core'? World server? Or just realm servers for both trinity and mangos?

From what I read so far I guess you want some server that can redirect incoming connections (well, initialization of an connection) from user to trinity/mangos realms based on some condition. Some kind of a proxy server. Is that what you want?

If so, I wouldn't modify any of the realm daemons, just put the proxy before it and let some external script switch between the realm daemons.

Link to comment
Share on other sites

I call the Core the mangos-worldd, cause the realmmanager is just a switch and at the worldd the playerdata would be calculatet.

Okay, i've seen the mistake (sry, but my english isn't soooo well) :)

I'll show you an example from the sending (from the old chatsystem) routine in VB6.

'Send Data to the Peer *ATTN: this is a SingleLineTicket
   If NameList(Client, 0) = "PEERINPROGRESS" Then
       If Winsock(PeerNumber).State = 7 Then Winsock(PeerNumber).SendData (data): DoEvents
       NameList(Client, 0) = "IDLE"
   End If

Now i would like to rebuild this code in C++....

The listensocket SOCKET will set an ID for every incomming connection, store it, ask at login for the worlddname, and if a worldd will send a command, the realmd is gathering the resiver worldd-name and store it in the XServermap.

Then the Worldd is sending the dataline (with the commands for the resiving worldd) to the realmd, the realmd will lookup to wich SOCKET ID the reciving worldd has and get its SOCKET ID (uint32 sessionID=GetSocket(); i guess), switch this socket as active and send.

And here I stuck, i don't know how to select the SOCKET ID and send to this... -.-

Thats all ;)

Link to comment
Share on other sites

Sorry, can't help with that. I don't know the exacts of communication between client and realmd/worldd, ie. at which point the connection get redirected to worldd and if some control part of the connection is left to the realmd (like port 21 for FTP CONTROL and 20 for FTP DATA). Furthermore, I know almost nothing about Winsock.

I'd do it using UDP - AF_INET socket, because local unix sockets, signals and probably winsocks aren't much portable.

Anyway I still didn't get your point, AFAIK you can use one native realmd to host more world daemons and some small compatibility fix with trinity worldd (if it's requied) shouldn't be problem.

Link to comment
Share on other sites

Would it help you to see what i have done in the source? ^_^

My English isn't the best to explain such things..... sry

But youre at the right way to understand my problem... :D

How do you manage more than one client connects to your UDP socket?

And how do you send some data to a connectet client (send back to the active client is working, but not to an other connectet client on the same port)...

pleeeze help me im lost in such things -.-

Link to comment
Share on other sites

Would it help you to see what i have done in the source? ^_^

My English isn't the best to explain such things..... sry

But youre at the right way to understand my problem... :D

How do you manage more than one client connects to your UDP socket?

And how do you send some data to a connectet client (send back to the active client is working, but not to an other connectet client on the same port)...

pleeeze help me im lost in such things -.-

Source? Rather not, I worked with old BASIC a loooooong time ago, so I'm not familiar with it that much ..

How a classic UDP connection works? Well, one side (server) opens a socket for listening and the other one just sends data to it. If you want to handle more clients on a listening socket, you may use poll() or select() for example. Of course this is just control connection on localhost. If you want to make a proxy and handle wow protocol, you need to use TCP or lower levels. See http://www.expertsforge.com/Programming/socket-programming-c-using-udp-with-code-87.asp (or any other googled page) for a simple C/C++ UDP server/client.

Link to comment
Share on other sites

Thank you so much for your patience and this usefull hint :)

I don't mean the Basic source (thats too easy) ;)

I mean my modified C++ Mangos Source (with WTF and o.O inside) xD

Actually I'm using an standart Telnet protokoll, to exchange the Data between Realmd and Worldd (not the player client data) .

It's telnet is very easy to handle and i have an console to connect to the server too, for testing purpose :D

If all works fine my Worldd 1 would make an 'Hello' announce to my other Worldd.

Link to comment
Share on other sites

So that's how it is, you just want one worldd to talk to other worldd, no realmd involved, right? Well the standard way of opening a connection should be easily googleable, but for mangos you probably need to make another thread to implement that correctly. Unfortunatelly, I can't help you with anything further, I'm not that advanced C++ programmer and don't know the thread system of this project.

Link to comment
Share on other sites

  • 2 months later...

Hi everyone, i'm back again...

For 3 Days ago, i've tried to rewrite the ServicePort...

And it works, my Worlddeamon sends some commands to others.

The ServicePort isn't really finished yet, but in 3-5 Days it should be.

I've tested it at a Windows and Linux, both are able to use this.

So i can announce, write mails, look at ticket from Worldd one, with Worldd two.

Character transfers will be supported in future (in 4 Days) :P

If all is working i'll publishing the sources in this Thread, please stand by.

Greetz GiR-Zippo-Booksized

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use