Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Mar 16th, 2006, 8:17 AM   #1
Xyhm
Programmer
 
Xyhm's Avatar
 
Join Date: Mar 2006
Posts: 60
Rep Power: 3 Xyhm is on a distinguished road
Networkprogramming in Unix

I'm having some problems with the following code. It's a server that takes some data from one or several clients, puts the data in a database (a multidimensional char) and sends the database to the client. Up to five clients should be able to connect, and it uses multiplexing to deal with these.

Here's a description of what works and what doesn't.

1. If I connect with one client, there is no problem. It connects, the client sends data, the server receives the data and puts it in the database which is then sent back to the client. The info that is sent back to the client is correct, and the client can keep sending data without any problem.

2. If client #1 connects but does NOT send any data, then client #2 can connect as well. But only the first of them (any of them) that sends data to the server, is going to succeed in sending. The server's select()-function won't unblock when the other client is trying to send data. (Also, the first one sending data can continue doing so without any problem.)

3. If client #1 connects and sends data, then client #2 won't be able to connect at all.

4. Lastly, a funny problem occurs when I don't include "break" in the section that handles new connections (see code). Namely, the new client connects, but then if(FD_ISSET(i, &read_set)) returns true for that new client socket(despite that this client hasn't sent anything yet) so the server ends up in wrong part of the code (it ends upp blocking at the read()-function when in fact it should end up blocking at the select()-function waiting for new data).

I have no idea what's wrong. I'm new to this stuff, so it could be something simple.

And now (drumroll), the code:

while(1){

      select(max_sock+1, &read_set, NULL, NULL, NULL);

      for(int i = 0; i <=  max_sock; i++){

         if(FD_ISSET(i, &read_set)){//Any socket ready?

            if(i == sock){//If new connection

               sock_new = accept(sock, (struct sockaddr *) &cliaddr, &len);

               if(sock_new == -1){
                  printf("Error in accept().\n"); fflush(stdout);
                  perror(strerror(errno));
               }

               if(sock_new > max_sock)
                  max_sock = sock_new;

               FD_SET(sock_new, &read_set);
               break;

            }else{//If previously established client wants to say something...

               if((read(sock_new, one_row, 10)) == -1){
                  printf("(klient) Error i read, errno: %i\n", errno); fflush(stdout);
                  perror(strerror(errno));
               }

               //Do stuff with data from client.

               if(((w = write(sock_new, db, 100))) == -1){
                  printf("Error in write (server).\n"); fflush(stdout);
                  perror(strerror(errno));
               }
               break;
            }
         }
      }

If anyone can tell me what's wrong, I will be feeling this way: :banana:
Xyhm is offline   Reply With Quote
Old Mar 17th, 2006, 9:24 AM   #2
jim mcnamara
Hobbyist Programmer
 
Join Date: Jun 2005
Location: New Mexico
Posts: 228
Rep Power: 4 jim mcnamara is on a distinguished road
The read does not appear to be a non-blocking read on the socket - ie., it sits there and waits forever which explains why more than one client fails.

This will make the socket you are reading on non-blocking (POSIX code)
#include <fcntl.h>
/* fd = socket id */
int setNonblocking(int fd)                                                     
{                                                                              
    int flags;                                                                 
                                                                               
    if ((flags = fcntl(fd, F_GETFL, 0)) == (-1)    )                             
    {
        flags = 0;                                                             
    }
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);                             
                                              
}
I would suggest reading at least chapter 5:

http://www.advancedlinuxprogramming.com/alp-folder

The ipc stuff is the same linux or not - it's all POSIX
jim mcnamara is offline   Reply With Quote
Old Mar 18th, 2006, 1:35 PM   #3
Xyhm
Programmer
 
Xyhm's Avatar
 
Join Date: Mar 2006
Posts: 60
Rep Power: 3 Xyhm is on a distinguished road
Quote:
Originally Posted by jim mcnamara
The read does not appear to be a non-blocking read on the socket - ie., it sits there and waits forever which explains why more than one client fails.
Read should be blocking. However, the program shouldn't end up in read() when there is nothing to read.

Anyway, the problem is solved now. There are two errors in the code:

1. "read_set" is modified in select(), so it needs to be re-assigned before each select() (one has to keep a master set to copy from).

2. In the read and write functions, "sock_new" should really be "i". (Clumsy error. The reason I put "sock_new" there in the first place is that this is a modified version of a server than only handled one client, where "sock_new" was all that was needed.)

(and 3. the "break"s shouldn't be there, but I knew that. That was just temporary solution to a problem I didn't understand. Now they are removed.)

I'll take a look at that book, thanks.
Xyhm is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 10:31 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC