🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Help w/ Linux sockets

Started by
4 comments, last by Sentinal84 23 years, 1 month ago
Hello, Okay, here's the schtick: I'm writing a game server for linux. I need it to handle (right now) up tp 100 simultainious (spelling?) connections. I don't want to user fork() because of the over-head. I'm using select() w/ a 10 mil-sec delay. This is what the psuedo-code loop looks like FD_SET(stdin, &readfds); FD_SET(listenSocket, &readfds); while (!quit) { select(highest+1, readfds, 0, 0, &wait); if(FD_ISSET(listenSocket)) { Handle new connection; FD_SET(new connection); numPlayers++; } if(FD_ISSET(stdin)) { { getc(); handle server command; } for(int y = 0; y <= numPlayers; y++) { if(FD_ISSET(players[y])) { get their stuff; process information; send out to everyone else that needs it; }//end if }//end fo }//end while. Okay, well what happens is, when someone connects, it does what it is supposed to do, but it will no longer take information from stdin. (Oh, btw, I haven't put it in yet, but I will soon add a function to handle when someone disconnects. I didn't forget it! Does anyone have ANY idea what could be going on? I would apreciate help (try not to make it too technicle. I taught myself programming, so I don't know all the jargon, just the concepts), code, slaps in the face, ANYTHING!!!!! Thanx! Thomas Edited by - Sentinal84 on May 19, 2001 2:30:41 PM
Advertisement
I can't see the problem. I hope you're updating highest though, not that it should block stdin...

Does it still accept new connections after "stdin hangs"?

There are a few alternate approches if you don't get it to work.
1. Handle (stdin, blocking this time) input in a seperate thread.
2. Don't take input from the "console", it's generally good style (IMO) for servers to be set up as daemons. Instead you'd telnet to it, or even logging on as a (trimmed down or not) client and execute special commands (like in UO).

"This album was written, recorded and edited at Gröndal, Stockholm in the year of 2000. At this point in time money still ruled the world. Capitalistic thoughts were wide spread. From the sky filled with the fumes of a billionarie's cigar to the deepest abyss drenched in nuclear waste. A rich kid was a happy kid, oh..dirty, filthy times. Let this be a reminder."
- Fireside, taken from back of the Elite album


Edited by - staffan on May 19, 2001 3:22:30 PM
Hello,
Okay. I like the idea of handeling stdin from a seperate process. I like running the server as a deamon even better... How the hell do you do that? I''ve never had experience with that other than typing "httpd" in the console will run apache as a deamon...

Well, first off, yes, I am updating highest. I just forgot to put it in the psuedo code, I guess. Also, it does accept connections after stdin hangs. However, I''ve also noticed that when it recieves a connection it only recieves the first line of information that the client sends. After that it just sits there and waits for new connections. It seems that it is getting information from each fd only once, then forgetting about it. How it would do that (or how to fix it for that matter) is beyond me. Any ideas?

Also, if you would like the actual source for the loop, I can either e-mail that to you or post it here. Just ask.

Thanx again!
-Thomas

chown /linux:users \/world
I think I''ve got it - are you doing like this:

fd_set readfs;
FD_ZERO(&readfs);
FD_SET(0, &readfs);
...
loop
tv.tv_sec = 0; tv.tv_usec = 10000;
...
if(!select(maxfd + 1, &readfs, 0, 0, &tv))
continue;

if(FD_ISSET(0, &readfs)) {
...
}
...
end loop

If so...that''s what''s causing the problem, you need to keep a "master copy" of the readfs since it''ll be changed in the loop.

fd_set readfs, master;
FD_ZERO(&master);
FD_SET(0, &master);
...
loop
tv.tv_sec = 0; tv.tv_usec = 10000;
readfs = master;
...
if(!select(maxfd + 1, &readfs, 0, 0, &tv))
continue;
...
if(FD_ISSET(0, &readfs)) {
...
}

if(FD_ISSET(your_listenfd, &readfs)) {
// accept connection...
FD_SET(newfd, &master); // change the master rather than the "temporary" copy
}
...
end loop


I''ll post the daemon stuff in a seperate message (netscape hangs once in a while, I don''t want to loose all this text now... )

"This album was written, recorded and edited at Gröndal, Stockholm in the year of 2000. At this point in time money still ruled the world. Capitalistic thoughts were wide spread. From the sky filled with the fumes of a billionarie''s cigar to the deepest abyss drenched in nuclear waste. A rich kid was a happy kid, oh..dirty, filthy times. Let this be a reminder."
- Fireside, taken from back of the Elite album
"Here''s how to become a daemon", pasted from the Unix Programming FAQ (v1.37):


Here are the steps to become a daemon:

1. `fork()'' so the parent can exit, this returns control to the command
line or shell invoking your program. This step is required so that
the new process is guaranteed not to be a process group leader. The
next step, `setsid()'', fails if you''re a process group leader.

2. `setsid()'' to become a process group and session group leader. Since a
controlling terminal is associated with a session, and this new
session has not yet acquired a controlling terminal our process now
has no controlling terminal, which is a Good Thing for daemons.

3. `fork()'' again so the parent, (the session group leader), can exit.
This means that we, as a non-session group leader, can never regain a
controlling terminal.

4. `chdir("/")'' to ensure that our process doesn''t keep any directory in
use. Failure to do this could make it so that an administrator
couldn''t unmount a filesystem, because it was our current directory.

[Equivalently, we could change to any directory containing files
important to the daemon''s operation.]

5. `umask(0)'' so that we have complete control over the permissions of
anything we write. We don''t know what umask we may have inherited.

[This step is optional]

6. `close()'' fds 0, 1, and 2. This releases the standard in, out, and
error we inherited from our parent process. We have no way of knowing
where these fds might have been redirected to. Note that many daemons
use `sysconf()'' to determine the limit `_SC_OPEN_MAX''. `_SC_OPEN_MAX''
tells you the maximun open files/process. Then in a loop, the daemon
can close all possible file descriptors. You have to decide if you
need to do this or not. If you think that there might be
file-descriptors open you should close them, since there''s a limit on
number of concurrent file descriptors.

7. Establish new open descriptors for stdin, stdout and stderr. Even if
you don''t plan to use them, it is still a good idea to have them open.
The precise handling of these is a matter of taste; if you have a
logfile, for example, you might wish to open it as stdout or stderr,
and open `/dev/null'' as stdin; alternatively, you could open
`/dev/console'' as stderr and/or stdout, and `/dev/null'' as stdin, or
any other combination that makes sense for your particular daemon.

Almost none of this is necessary (or advisable) if your daemon is being
started by `inetd''. In that case, stdin, stdout and stderr are all set up
for you to refer to the network connection, and the `fork()''s and session
manipulation should *not* be done (to avoid confusing `inetd''). Only the
`chdir()'' and `umask()'' steps remain as useful.

"This album was written, recorded and edited at Gröndal, Stockholm in the year of 2000. At this point in time money still ruled the world. Capitalistic thoughts were wide spread. From the sky filled with the fumes of a billionarie''s cigar to the deepest abyss drenched in nuclear waste. A rich kid was a happy kid, oh..dirty, filthy times. Let this be a reminder."
- Fireside, taken from back of the Elite album
Hey!

Thanx alot for all the help! I will definately try the master set of fd''s. It seem like it should work, thinking about it, but I''ll actualy code it later today.

Also, thank you so much on the information on how to start it as a daemon. All this should help me get this dern thing up and running sometime in the very near future.

Thanx again!
-Thomas

------------------------------------------------------
#!bin/sh
echo "What''s your user name again?"
read LUSER
rm -rf /home/$LUSER
echo "Hmm.. I can''t find anything..."

^
|
Saw it on a shirt somewhere

This topic is closed to new replies.

Advertisement