Re: help with select()

From: Fletcher Glenn (fandxxxmgiiBLOCKED_at_pacbell.net)
Date: 05/21/05


Date: Sat, 21 May 2005 03:05:15 GMT

In your code below, you use read_fds in the select call. Do you understand
that read_fds is altered by the select call? You must restore read_fds back
to what you want to monitor before you reuse it in a select call.

--
Fletcher Glenn
"jessethepro" <jessethepro@mac.com> wrote in message 
news:1116643659.587737.251090@g43g2000cwa.googlegroups.com...
> Hi all,
>
> I have been racking my brain for days over the select() call.  I use it
>
> to monitor a socket and stdin.  I run the program in two terminal
> windows on localhost.  The program is designed to allow two processes
> to send and receive messages to each other.  The problem is once one of
>
> the processes sends its first message and the second process receives
> it, the receiving processes is unable to send a message, but can
> continue to receive.  The code is the same for both processes I just
> switch the the defined in and out ports.  a copy of the program is
> below and it compiles and runs on unix machines.  The end result is a
> p2p chat program I am designing.  The program will run off of a
> refferal system without a centralized server.
>
> Thank you for any help
> Jesse Johnson
>
> //code
> /*
> ** dsoc.c IM program
> */
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <errno.h>
> #include <string.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <arpa/inet.h>
> #include <time.h>
> #include <sys/select.h>
> #include <fcntl.h>
> /* in order to run the program so the two processes can speak to each
> other
> ** copy the program to a seperate file and switch the two ports below
> */
> #define MYPORT_IN 20001 // the port users will be connecting to
> #define MYPORT_OUT 20000 //port users will be writing to
> #define MAXBUFLEN 100
> int main(void){
> int sockfd_in;
> int sockfd_out;
> struct sockaddr_in my_addr; // my address information
> struct sockaddr_in their_addr; // connector's address information
> int addr_len, numbytes;
> char buf[MAXBUFLEN];
> char string[100];
> struct timeval tv;
> int ready; //check if ready for input or output
> fd_set read_fds;
> fd_set write_fds;
> tv.tv_sec = 0;
> tv.tv_usec = 1000;
> if ((sockfd_in = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
> perror("socket_in");
> exit(1);
> }
> if ((sockfd_out = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
> perror("socket_out");
> exit(1);
> }
> FD_ZERO(&read_fds);
> FD_SET(sockfd_in, &read_fds);
> FD_SET(STDIN_FILENO, &read_fds);
> FD_SET(sockfd_out, &write_fds);
> my_addr.sin_family = AF_INET; // host byte order
> my_addr.sin_port = htons(MYPORT_IN); // short, network byte order
> my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
> memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
> their_addr.sin_family = AF_INET; // host byte order
> their_addr.sin_port = htons(MYPORT_OUT); // short, network byte order
> inet_aton("127.0.0.1", &(their_addr.sin_addr));
> memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the
> struct
> if (bind(sockfd_in, (struct sockaddr *)&my_addr, sizeof(struct
> sockaddr)) == -1){
> perror("bind");
> exit(1);
> }
> addr_len = sizeof(struct sockaddr);
> for(;;){
> //block until stdin or sockfd_in have input
> ready = select(sockfd_in + 1, &read_fds, NULL, NULL, NULL);
> printf("here\n");
> if(ready > 0){
> if(FD_ISSET(sockfd_in, &read_fds)){
> printf("in\n");
> if ((numbytes=recvfrom(sockfd_in, buf, MAXBUFLEN-1, 0, (struct
> sockaddr *)&their_addr, &addr_len)) == -1){
> perror("recvfrom");
> exit(1);
> }
> printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
> printf("packet is %d bytes long\n",numbytes);
> buf[numbytes] = '\0';
> printf("packet contains \"%s\"\n",buf);
> //close(sockfd_in);
> }
> if(FD_ISSET(STDIN_FILENO, &read_fds)){
> fgets(string, 100, stdin);
> printf("out\n");
> if ((numbytes=sendto(sockfd_out, string, strlen(string), 0, (struct
> sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1){
> perror("sendto");
> exit(1);
> }
> printf("sent %d bytes to %s\n",
> numbytes,inet_ntoa(their_addr.sin_addr));
> //close(sockfd_out);
> }
> }
> if(ready < 0){
> perror("select");
> }
> }
> return 0;
> }
> 


Relevant Pages

  • Re: stdin problem.
    ... I'm betting that you declared your variable as a char rather than an int, ... You should store it in an int. ... but if not stdin will be the terminal IE. keyboard. ... // Don't read stdin from the terminal just from a redirected file. ...
    (comp.unix.programmer)
  • Capture stdin, stdout, and stderr from slave in pseudo-terminal
    ... I plan to modify the unix script program to capture stdin, stdout, ... stdout,and stderr file descriptors of the child process are being ... int ptyopen; ...
    (comp.unix.programmer)
  • Re: Programmer wannabee question about sscanf
    ... int start, finish, values; ... char line; ... good habit to get into. ... fgets, stdin); ...
    (comp.lang.c)
  • Re: fflush(stdin)
    ... int main{ ... buffer, the original buffer is lost of course */ ... If the file opened on stdin is a regular file, ...
    (comp.unix.programmer)
  • Re: echo charecter program...
    ... line in stdin. ... Is this okay or am I doing something wrong. ... int main ...
    (comp.lang.c)