UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » Networking
  • » Using select() for a datagram socket server compared to a stream socke

#1 2010-11-22 09:15 AM

SeriousTyro
Member
Registered: 2010-11-22
Posts: 2

Using select() for a datagram socket server compared to a stream socke

Hey guys, so far I've been using selectserver.c from Beej's Guide, as the basis for my programming assignment and it has gotten me pretty far. I've been avoiding trying to learn how to implement select( ) with Beej's datagram socket server server.c but the next assignment will be require us to use a datagram socket and I can't "cheat" my way out using a stream.

So I was trying to match what I would need for a datagram server that uses select () and got stuck as to what I should put in and take out.

In this code:

for(i = 0; i <= fdmax; i++) {
            if (FD_ISSET(i, &read_fds)) { // we got one!!
                if (i == listener) {
                    // handle new connections
                    addrlen = sizeof remoteaddr;
                    newfd = accept(listener,
                        (struct sockaddr *)&remoteaddr,
                        &addrlen);

                    if (newfd == -1) {
                        perror("accept");
                    } else {
                        FD_SET(newfd, &master); // add to master set
                        if (newfd > fdmax) {    // keep track of the max
                            fdmax = newfd;
                        }
                        printf("selectserver: new connection from %s on "
                            "socket %d\n",
                            inet_ntop(remoteaddr.ss_family,
                                get_in_addr((struct sockaddr*)&remoteaddr),
                                remoteIP, INET6_ADDRSTRLEN),
                            newfd);
                    }
                } else {
                    // handle data from a client
                    if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
                        // got error or connection closed by client
                        if (nbytes == 0) {
                            // connection closed
                            printf("selectserver: socket %d hung up\n", i);
                        } else {
                            perror("recv");
                        }
                        close(i); // bye!
                        FD_CLR(i, &master); // remove from master set
                    } else {
                        // we got some data from a client
                        for(j = 0; j <= fdmax; j++) {
                            // send to everyone!
                            if (FD_ISSET(j, &master)) {
                                // except the listener and ourselves
                                if (j != listener && j != i) {
                                    if (send(j, buf, nbytes, 0) == -1) {
                                        perror("send");
                                    }
                                }
                            }
                        }
                    }
                } // END handle data from client
            } // END got new incoming connection
        } // END looping through file descriptors

I was wondering how I would adjust

if (i == listener) {
                    // handle new connections
                    addrlen = sizeof remoteaddr;
                    newfd = accept(listener,
                        (struct sockaddr *)&remoteaddr,
                        &addrlen);

                    if (newfd == -1) {
                        perror("accept");
                    } else {
                        FD_SET(newfd, &master); // add to master set
                        if (newfd > fdmax) {    // keep track of the max
                            fdmax = newfd;
                        }
                        printf("selectserver: new connection from %s on "
                            "socket %d\n",
                            inet_ntop(remoteaddr.ss_family,
                                get_in_addr((struct sockaddr*)&remoteaddr),
                                remoteIP, INET6_ADDRSTRLEN),
                            newfd);
                    }
                } else {

such that it would be used for a datagram. I now for sure I do not need the accept( ) thus I would not need the newfd but I was wondering how I would keep track of the fdmax like in

FD_SET(newfd, &master); // add to master set
                        if (newfd > fdmax) {    // keep track of the max
                            fdmax = newfd;
                        }

Offline

#2 2010-11-22 01:06 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,826
Website

Re: Using select() for a datagram socket server compared to a stream socke

With a datagram socket, you only really need a single socket to handle all requests and replies...  There are no separate connections for each client...  So, the entire "listener"/accept() section can be removed entirely, and your "fdmax" stays fixed to your lone socket FD value, which is the only FD that'll be in your fd_set as well...  When that lone socket selects readable, you'll just do a recvfrom() and whatever processing you're supposed to do to the data, then probably a sendto() for a reply...

Offline

#3 2010-11-22 06:32 PM

SeriousTyro
Member
Registered: 2010-11-22
Posts: 2

Re: Using select() for a datagram socket server compared to a stream socke

Thanks a lot, I think I'll be able to take it from there! =)

Offline

#4 2013-09-28 11:41 PM

Mridul
Guest

Re: Using select() for a datagram socket server compared to a stream socke

Thank you very much....i have the same doubt.

  • Index
  • » Networking
  • » Using select() for a datagram socket server compared to a stream socke

Board footer

Powered by FluxBB