• Welcome to Valhalla Legends Archive.
 

Creating A Server

Started by Final, March 11, 2006, 01:31 PM

Previous topic - Next topic

Final

Hey Guys whats up Ive been working on making a server for a game a friend of mine and me are doing and im doing the server but I have a problem how can I make it hold more than one user in the server.
Its using winsock asynchronous.
He gave me an example in vb but How does Index Work?
All I want to know is how to accept more than 1 user and keep the connections going?

Yegg

Quote from: Final on March 11, 2006, 01:31 PM
Hey Guys whats up Ive been working on making a server for a game a friend of mine and me are doing and im doing the server but I have a problem how can I make it hold more than one user in the server.
Its using winsock asynchronous.
He gave me an example in vb but How does Index Work?
All I want to know is how to accept more than 1 user and keep the connections going?

Well, have you got any code written so far? And what is this "Index" you speak of?

Kp

Don't close the socket of the first user when you accept a connection from the second user!
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Final

Ok let me show you what im working with.

            case WM_SOCKET:
    {
if (WSAGETSELECTERROR(lparam))
{ // error!
PostQuitMessage (0);
}
switch (WSAGETSELECTEVENT(lparam))
{
            case FD_READ:
            {
             
              int ncmdshow;
              ZeroMemory(packetbuffer, 256);
              ncmdshow = recv(s, packetbuffer, 256, 0);
              //parse();
              //char* string=packet+intwereitstarts;
              ncmdshow = send(wParam, packetbuffer, strlen(packetbuffer), 0);
              SendMessage(hedit_2, WS_VSCROLL, SB_LINEDOWN, 0);
            } break;
            case FD_WRITE:
            {
            } break;
            case FD_ACCEPT:
              {
               int ncmdshow;
               char buffer[256];
               char strTem[5000];
               char sa[MAX_PATH];
               char* sp="\n";
               s=accept(wParam,NULL, NULL);
               cout<<wParam<<endl;
               GetWindowText(hedit_2, strTem, 5000);
               sprintf(sa, "%s%s%s", strTem,sp,"A User has Connected to the Server");
               SetWindowText(hedit_2,sa);
               ncmdshow = send(wParam, sa, strlen(sa), 0);
               SendMessage(hedit_2, WS_VSCROLL, SB_LINEDOWN, 0);
                } break;
                case FD_CLOSE:
                 {
                char strTem[5000];
               char sa[MAX_PATH];
               char* sp="\n";
               GetWindowText(hedit_2, strTem, 5000);
               sprintf(sa, "%s%s%s", strTem,sp,"A User has disconnected to the Server");
               SetWindowText(hedit_2,sa);
               SendMessage(hedit_2, EM_SCROLL, SB_LINEDOWN, 0);
                  } break;
}
} break;
//Socket End//

FrOzeN

Quote from: Final on March 11, 2006, 01:31 PM
He gave me an example in vb but How does Index Work?
Don't try comparing the example I gave you in VB6 to C++. Index was the current item in the control array of Winsock.

So whatever the varible your using to create the socket, make it an array so you can setup multiple connections with ease of working with the varibles.

Other than that C++ is pretty obsolete to me atm, so I can't really follow up any more questions that arise based on arrays in C++ etc..
~ FrOzeN

Final

Could someone still help me out on it being able to handle more than one connection and keeping it on or take it out if the person leaves.

Kp

Quote from: Final on March 12, 2006, 04:02 AM
Ok let me show you what im working with.

Since you've already indicated you're new to this, I won't hold the following code against you.  That said, it's really bad code. :)

Quote from: Final on March 12, 2006, 04:02 AM
            case WM_SOCKET:
    {
if (WSAGETSELECTERROR(lparam))
{ // error!
PostQuitMessage (0);
}
switch (WSAGETSELECTEVENT(lparam))
{
            case FD_READ:
            {
             
              int ncmdshow;
              ZeroMemory(packetbuffer, 256);

First mistake: don't use magic numbers.  From context, I'm guessing that 256 is the number of bytes in packetbuffer (i.e. that you did char packetbuffer[256]; somewhere that didn't get pasted).  It's better to specify that you want the compiler to compute the size automatically.  Then, if it ever changes, the compiler automatically uses the new value when you rebuild.  Use ZeroMemory(packetbuffer, sizeof(packetbuffer));.

Quote from: Final on March 12, 2006, 04:02 AM
              ncmdshow = recv(s, packetbuffer, 256, 0);

Ditto the magic number issue for the recv(2) call.  You're not checking whether the recv(2) failed (or returned that the connection closed (both of which may be a non-issue for the particular type of event-driven I/O you're doing, but it's worth keeping in mind)).  Also, calling the recv(2) result ncmdshow looks a bit weird.

Quote from: Final on March 12, 2006, 04:02 AM
              //parse();
              //char* string=packet+intwereitstarts;

It's better not to name variables string, since then you can't use STL's std::string without a fully qualified name.  This is just a style issue. :)

Quote from: Final on March 12, 2006, 04:02 AM
              ncmdshow = send(wParam, packetbuffer, strlen(packetbuffer), 0);

You're assuming that the client will send a null-terminated message.  If it doesn't, that strlen will walk off the end of packetbuffer looking for a null.  If you're just trying to echo the result back, pass the amount received as the length parameter of send(2).

Quote from: Final on March 12, 2006, 04:02 AM
              SendMessage(hedit_2, WS_VSCROLL, SB_LINEDOWN, 0);

WS_VSCROLL is a style, not a message.  If the SendMessage call has any effect at all, it probably won't be what you want.

Quote from: Final on March 12, 2006, 04:02 AM
            } break;
            case FD_WRITE:
            {
            } break;
            case FD_ACCEPT:
              {
               int ncmdshow;
               char buffer[256];
               char strTem[5000];
               char sa[MAX_PATH];
               char* sp="\n";
               s=accept(wParam,NULL, NULL);
               cout<<wParam<<endl;
               GetWindowText(hedit_2, strTem, 5000);

Unicode cleanliness issue: you're using GetWindowText, which takes a TCHAR *, with a char[] argument.  This will work in MBCS mode, but breaks in Unicode mode.  Use GetWindowTextA or switch strTem to be a TCHAR[] array.  You may need to include <tchar.h> for the latter change.  Also, magic numbers again. :)

Also, buffer is unused.

Quote from: Final on March 12, 2006, 04:02 AM
               sprintf(sa, "%s%s%s", strTem,sp,"A User has Connected to the Server");

Looks a little weird, is wasteful, and badly susceptible to a buffer overflow.  MAX_PATH is only 260 on Windows, so you can easily overrun sa and have bad things happen.  The canonical workaround for the lack of good output devices on Windows is to programmatically select a zero-length region anchored at the end of the control, then replace its contents with the message you want to add.  See EM_SETSEL and EM_REPLACESEL.

Consider using _snprintf to get bounds-limited formatting.  Note that Microsoft's _snprintf stupidly doesn't null-terminate its output like GNU libc's snprintf does.  So, you'll see a lot of constructs of the form:


_snprintf(buf, sizeof(buf) - 1, "format_string", <args>);
buf[(sizeof(buf) / sizeof(buf[0])) - 1] = 0;


Quote from: Final on March 12, 2006, 04:02 AM
               SetWindowText(hedit_2,sa);

Unicode cleanliness again.  Consider SetWindowTextA if you left sa as a char[].

Quote from: Final on March 12, 2006, 04:02 AM
               ncmdshow = send(wParam, sa, strlen(sa), 0);

Do you really intend to be sending back the entire contents to every new user?

Quote from: Final on March 12, 2006, 04:02 AM
               SendMessage(hedit_2, WS_VSCROLL, SB_LINEDOWN, 0);

Again, WS_VSCROLL.

Quote from: Final on March 12, 2006, 04:02 AM
                } break;
                case FD_CLOSE:
                 {
                char strTem[5000];
               char sa[MAX_PATH];
               char* sp="\n";
               GetWindowText(hedit_2, strTem, 5000);
               sprintf(sa, "%s%s%s", strTem,sp,"A User has disconnected to the Server");
               SetWindowText(hedit_2,sa);

Same issues as in FD_READ.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Final

#7
Thanks for that much.
But After A while of talking with frozen and reading some resource I managed to hold connections now my problem is how do i send a message to all my users that are connected.
There all under a socket array.
But for some reason I cant send anything to them? could someone help me out.

rabbit

Loop through the array and call send() on each with the data you want to send.
Grif: Yeah, and the people in the red states are mad because the people in the blue states are mean to them and want them to pay money for roads and schools instead of cool things like NASCAR and shotguns.  Also, there's something about ketchup in there.

Final

#9
I already tried that.
unless Im Accepting it wrong

this is how I was accepting it.

array[#] '=' accept(stuff,NULL,NULL);



What am I doing wrong.

FrOzeN

Huh? You just said you were able to hold your connections. When connections arrive on the port your listening to you recieve a request in which you either accept or decline the connection.

If you haven't got past the stage of accepting the connections properally. Then the statement "I managed to hold connections now" is very far off. Just trying to point this out, because the terminology your using is probably making it bit confusing for the others to understand where your up to.

I can't exactly help with any of the coding, I can only provide the pseudo method in which it has to be done.
~ FrOzeN

Final

Sorry About that what I mean is holding Connection Info To play with. To send information to everyone but nevermind I finally got it done I had done something wrong witht the loop but i fixed it and it works fine now. Thankyou everyone for all the help that you gave me I really appreciate it all.