![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Programmer
Join Date: Mar 2006
Posts: 60
Rep Power: 3
![]() |
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: |
|
|
|
|
|
#2 |
|
Hobbyist Programmer
Join Date: Jun 2005
Location: New Mexico
Posts: 228
Rep Power: 4
![]() |
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);
}http://www.advancedlinuxprogramming.com/alp-folder The ipc stuff is the same linux or not - it's all POSIX |
|
|
|
|
|
#3 | |
|
Programmer
Join Date: Mar 2006
Posts: 60
Rep Power: 3
![]() |
Quote:
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. |
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|