|
Home > Archive > Unix Programming > January 2004 > Select() and Beejs Network Programming Tutorial
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Select() and Beejs Network Programming Tutorial
|
|
| Materialised 2004-01-24, 11:34 am |
| Hi everyone, today I started reading Beejs Guide to Network programming,
however I am having a issue with select().
I have compiled the code sample he gives on select() (listed below) and
for some reason I get errors when running.
I even tired it on 2 different machines, a Freebsd 5.1 x86 system and a
redhat 8.0 alpha system just to double check.
Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 9034 // port were listening on
int main(void)
{
fd_set master; //master file descriptor list
fd_set read_fds; //temp file descriptor list for select()
struct sockaddr_in myaddr; //server address
struct sockaddr_in remoteaddr; //client address
int fdmax; //max file descriptor number
int listener; //listening socket descriptor
int newfd; //newly accept()ed socket descriptor
char buf[256]; //buffer for client data
int nbytes;
int yes=1; //for setsocketopt() SO_REUSEADDR, below
int addrlen;
int i, j;
FD_ZERO(&master);
FD_ZERO(&read_fds);
//get the listener
if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
//loose the pesky "address in use" error message
if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) ==
-1) {
perror("setsockopt");
exit(1);
}
//bind
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_port = htons(PORT);
memset(&(myaddr.sin_zero), '\0', 8);
if(bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) {
perror("bind");
exit(1);
}
//listen
if(listen(listener, 10) == -1) {
perror("listen");
exit(1);
}
//add the listener to the master set
FD_SET(listener, &master);
//keep track of the biggest file descriptor
fdmax = listener; //so far its this one
//main loop
for(;;) {
read_fds = master; //copy it
if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
perror("select");
exit(1);
}
//run through the existing connections looking for data to send
for(i=0; i <= fdmax; i++) {
if(FD_ISSET(i, &read_fds)) { //we got one!!!
if(i == listener) {
//handle new connections
addrlen = sizeof(remoteaddr);
if((newfd = accept(listener, (struct sockaddr *)&remoteaddr,
&addrlen)) == -1) {
perror("accept");
} else {
//handle data from the client
if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
//got error or the conenction was close by the 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 the 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");
}
}
}
}
}
} //its so ugly
}
}
}
}
return 0;
And here are the error messages I recieve, for some reason the server
will only allow one client to connect.
######### F'BSD Machine
recv: Socket is not connected
######### RedHat Machine
recv: Transport endpoint is not connected
I have no idea what is wrong here, is it the code provided in the
tutorial? my systems, or have I simply errored somewhere in typing it
out? (I did check for the later, but I couldnt see anything apparent.)
Thanks for your help
Mick
--
Materialised
| |
| frmb@kent.ac.uk 2004-01-24, 3:34 pm |
| Materialised <materialised@privacy.net> usenetted:quote:
>[snip code]
> if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
Looks like it should be "newfd" instead of "i", at a guess.
Hope that helps,
--
Fred
| |
| Gianni Mariani 2004-01-24, 4:34 pm |
| Materialised wrote:quote:
> Hi everyone, today I started reading Beejs Guide to Network programming,
> however I am having a issue with select().
> I have compiled the code sample he gives on select() (listed below) and
> for some reason I get errors when running.
> I even tired it on 2 different machines, a Freebsd 5.1 x86 system and a
> redhat 8.0 alpha system just to double check.
>
> Here is the code
.... snip...quote:
>
> //run through the existing connections looking for data to send
> for(i=0; i <= fdmax; i++) {
> if(FD_ISSET(i, &read_fds)) { //we got one!!!
> if(i == listener) {
> //handle new connections
> addrlen = sizeof(remoteaddr);
> if((newfd = accept(listener, (struct sockaddr
> *)&remoteaddr,
> &addrlen)) == -1) {
> perror("accept");
.... newfd is the magic fd that needs to be read and written to
but it's dropped on the floor.
It seems like the "if(i == listener)" else is messed up with the
"if((newfd = ..." else but there is somthing else (like an FD_SET) missing.
quote:
> } else {
> //handle data from the client
> if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
> //got error or the conenction was close by
> the client
.....
quote:
> I have no idea what is wrong here, is it the code provided in the
> tutorial? my systems, or have I simply errored somewhere in typing it
> out? (I did check for the later, but I couldnt see anything apparent.)
You probably have a few missing lines.
| |
| Barry Margolin 2004-01-24, 6:34 pm |
| In article <amfvub.ako.ln@teddy.frmb.org>, frmb@kent.ac.uk wrote:
quote:
> Materialised <materialised@privacy.net> usenetted:
>
> Looks like it should be "newfd" instead of "i", at a guess.
No, i is the fd that was just checked with FD_ISSET(). newfd is from a
previous iteration when the listening fd was ready.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
| |
| frmb@kent.ac.uk 2004-01-25, 2:34 am |
| Barry Margolin <barmar@alum.mit.edu> usenetted:quote:
>
> No, i is the fd that was just checked with FD_ISSET(). newfd is from a
> previous iteration when the listening fd was ready.
So it is.. that'll teach me to read code at 4am.. ;)
--
Fred
| |
| Materialised 2004-01-25, 4:35 am |
| Gianni Mariani wrote:
<snip>quote:
> You probably have a few missing lines.
>
Yeah that was the problem, fool on me 
--
Materialised
|
|
|
|
|