Berkely Socket Accept.. not working, ideas?

J

Jim

Need some comments from anyone willing to help, please. See the code
included below. This compiles with GCC on FreeBSD 4.7. The only
point of it is to accept a socket connection. Nothing else has been
implemented.

It does not work. Everything matches how it should be (according to
the man pages on the relevant functions). It also matches line by
line with code from another application used as a known to be working
reference. Infact, some of the code is cut-and-paste from that
application. I re-compiled that application to ensure that it really
does work.. and it does. This code here, derived from it, does not.
As far as I can tell this should should be working but doesn't. It
failes with an EINVAL error on the accept() call.

I'd love any comments anyone would like to offer.

Thanks
-J



Here is the output of the compiled program being run (its called
"bcs") and the result when someone telnets to the port it is
listenining on (port 811):

bash-2.05b# uname -a
FreeBSD 4.7-RELEASE FreeBSD 4.7-RELEASE #22: Wed Aug 6 22:12:16 GMT
2003 root@:/usr/src/sys/compile/mykern i386
bash-2.05b#
bash-2.05b# ./bcs

DEBUG2
DEBUG3
accept: Invalid argument
bash-2.05b#


Here is the actual code in its entirety:

1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/types.h>
4 #include <sys/socket.h>
5 #include <sys/file.h>
6 #include <netinet/in.h>
7 #include <time.h>
8 #include <ctype.h>
9 #include <unistd.h>
10 #include <errno.h>
11
12
13 int main ()
14 {
15 struct sockaddr addr;
16 int addrlen;
17 struct sockaddr salocal;
18 struct sockaddr_in *sin;
19 int rlistenfd;
20 int remotefd;
21 int result;
22 int status;
23 fd_set readfds;
24
25 remotefd = -1;
26
27 rlistenfd = socket(AF_INET, SOCK_STREAM,0);
28 if (rlistenfd < 0) {
29 (void)perror("socket");
30 exit(-1);
31 }
32 sin = (struct sockaddr_in *) & salocal;
33 memset ((char *) sin, '\0', sizeof (salocal));
34 sin->sin_family = AF_INET;
35 sin->sin_addr.s_addr = INADDR_ANY;
36 sin->sin_port = htons(811);
37 result = bind (rlistenfd, & salocal, sizeof (*sin));
38 if (result < 0) {
39 (void) perror ("bind");
40 exit(-1);
41 }
42 if(listen(rlistenfd, 2)) {
43 (void) perror ("listen");
44 exit(-1);
45 }
46
47 for(;;) {
48 FD_ZERO(&readfds);
49 FD_SET(rlistenfd, &readfds);
50
51 status = select(32, &readfds, NULL, NULL,
NULL);
52 if(status == -1) {
53 printf("DEBUG1\n");
54 if (errno == EINTR)
55 continue;
56 (void)perror("main:select");
57 printf("select status=%d\n", status);
58 exit(-1);
59 }
60 if(FD_ISSET(rlistenfd, &readfds)) {
61 printf("DEBUG2\n");
62 remotefd = accept(rlistenfd, &addr,
&addrlen);
63 if(remotefd==-1) {
64 printf("DEBUG3\n");
65 (void) perror("accept");
66 exit(1);
67 continue;
68 }
69 }
70 } /* for */
71 }
72
 
C

CBFalconer

Jim said:
Need some comments from anyone willing to help, please. See the
code included below. This compiles with GCC on FreeBSD 4.7. The
only point of it is to accept a socket connection. Nothing else
has been implemented.
Sockets are not mentioned in the C standard.

.... snip ...
I'd love any comments anyone would like to offer.
.... snip ...

Here is the actual code in its entirety:

1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/types.h>
4 #include <sys/socket.h>
5 #include <sys/file.h>
6 #include <netinet/in.h>
7 #include <time.h>
8 #include <ctype.h>
9 #include <unistd.h>
10 #include <errno.h>

Only lines 1,2, 7, 8, and 10 are valid under standard C. The rest
are non-standard. This is far off topic for c.l.c, but see the
references below for more appropriate newsgroups.

--
Some useful references:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://www.eskimo.com/~scs/C-faq/top.html>
<http://benpfaff.org/writings/clc/off-topic.html>
<http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/> (C99)
 
M

Materialised

Jim said:
Need some comments from anyone willing to help, please. See the code
included below. This compiles with GCC on FreeBSD 4.7. The only
point of it is to accept a socket connection. Nothing else has been
implemented.

It does not work. Everything matches how it should be (according to
the man pages on the relevant functions). It also matches line by
line with code from another application used as a known to be working
reference. Infact, some of the code is cut-and-paste from that
application. I re-compiled that application to ensure that it really
does work.. and it does. This code here, derived from it, does not.
As far as I can tell this should should be working but doesn't. It
failes with an EINVAL error on the accept() call.
check this out:

http://www.ecst.csuchico.edu/~beej/guide/net/html/advanced.html#select
 
C

Charles Banas

Jim said:
Need some comments from anyone willing to help, please. See the code
included below. This compiles with GCC on FreeBSD 4.7. The only
point of it is to accept a socket connection. Nothing else has been
implemented.
this is more topical in comp.unix.programmer. i'd recomment posting there.
 
C

CBFalconer

Richard said:
You didn't initialize addrlen.

There is no reason to initialize addrlen. The function accept is
undefined, and you would have to look at its source. This
illustrates why you should not answer off-topic questions other
than by referring to a suitable group.
 
R

Richard Tobin

CBFalconer said:
There is no reason to initialize addrlen. The function accept is
undefined, and you would have to look at its source. This
illustrates why you should not answer off-topic questions other
than by referring to a suitable group.

Don't be silly.

-- Richard
 
K

Keith Thompson

CBFalconer said:
There is no reason to initialize addrlen. The function accept is
undefined, and you would have to look at its source. This
illustrates why you should not answer off-topic questions other
than by referring to a suitable group.

In fact, without seeing the documentation for the accept() function,
we have no way of knowing whether addrlen needs to be initialized
before the call. If accept() merely writes a result to the object
pointed to by its third argument, and ignores any previous value of
that object, then it's not necessary to initialize addrlen. If, on
the other hand, accept()'s third argument is used both to pass
information into the function and to return information to the caller,
then it may be necessary to initialize addrlen before the call.

I happen to know that accept() is defined by POSIX. I've just checked
the documentation (a man page on a Linux system -- which also has a
long note about a controversy regarding the third argument) so I know
whether addrlen needs to be initialized before the call. But as
CBFalconer correctly points out, that's off-topic here. Even if he's
mistaken about whether addrlen needs to be initialized, it still tends
to confirm that this isn't the place to discuss it.

If the original poster hasn't already found the answer to his
question, he should try comp.unix.programmer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top