Professional Web Applications Themes

Help with Select - UNIX Programming

Hi, I am trying to use the select() socket programming command to select between stdin and a connection. Currently, I have a listening stream and stdin that I insert into the fd_set. The problem is that when I recognize FD_ISSET from stdin, I am stuck there. The loop does not return me to select() between stdin and listening socket. Similarly, when I accept a client, the loop does not return me to select between stdin and listeing socket. I don't know what to do. I want to be able to select continuously between stdin and the listening port after I ...

  1. #1

    Default Help with Select

    Hi,

    I am trying to use the select() socket programming command to select between
    stdin and a connection. Currently, I have a listening stream and stdin that
    I insert into the fd_set. The problem is that when I recognize FD_ISSET from
    stdin, I am stuck there. The loop does not return me to select() between
    stdin and listening socket. Similarly, when I accept a client, the loop does
    not return me to select between stdin and listeing socket. I don't know what
    to do. I want to be able to select continuously between stdin and the
    listening port after I have either accepted from a port or from stdin.

    I have pasted the codes that I am using for the listening to port and stdin
    and the code for the client.

    Please help.

    Thank you,

    Marcia Hon

    #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 max(a, b) ((a) > (b) ? a: b)

    int flushToEndOfLine();

    int main(int argc, char *argv[])

    {

    fd_set master;


    struct sockaddr_in myaddr;

    struct sockaddr_in remoteaddr;


    int fdmax;

    int listenerSocket;

    int newfd;

    char buf[256];

    int yes = 1;

    int addrlen;

    int i, j;


    if(argc != 2)

    {

    fprintf(stderr, "Usage: %s <listen_port>\n", argv[0]);

    exit(1);

    }


    FD_ZERO(&master); //clear master set


    // get listenerSocket

    if((listenerSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

    perror("socket");

    exit(1);

    }


    // lose socket already in use error message

    if(setsockopt(listenerSocket, 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(atoi(argv[1]));

    memset(&(myaddr.sin_zero), '\0', 8);

    if(bind(listenerSocket, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1)
    {

    perror("bind");

    exit(1);

    }


    // listen

    if(listen(listenerSocket, 5) == -1) {

    perror("listen");

    exit(1);

    }


    FD_SET(listenerSocket, &master);

    FD_SET(0, &master);


    fdmax = max(listenerSocket, 0);


    while(1){

    printf("select\n");

    if(select(fdmax+1, &master, NULL, NULL, NULL) == -1){

    perror("select");

    exit(1);

    }


    if(FD_ISSET(listenerSocket, &master)){

    addrlen = sizeof(remoteaddr);

    if((newfd = accept(listenerSocket, (struct

    sockaddr *)&remoteaddr, &addrlen)) == -1) {

    perror("accept");

    }

    printf("new connection from client\n");

    close(newfd);

    }

    else

    {

    if(FD_ISSET(0, &master))

    {

    printf("user entered data \n");

    flushToEndOfLine();

    }

    }

    }


    return 0;

    }

    int flushToEndOfLine()

    {

    int c;

    while ( (c=getchar()) != EOF && c != '\n' );

    return;

    }



    client:

    //WHAT IF SHORT IS NOT 2 BYTES?!?!?!?

    #include <stdio.h>

    #include <stdlib.h>

    #include <sys/socket.h>

    #include <sys/types.h>

    #include <netinet/in.h>

    #include <arpa/inet.h>

    #include <netdb.h>

    #define FILE_TBYTES 4 //bytes at the beginning of file that specify how many
    bytes are in this block being sent

    #define MAX_BYTES 1000 //breaks up file into this many bytes and sends this
    many bytes at a time

    #define MAX_BSEND_RETRY 3 //how many times to retry sending a block of
    MAX_BYTES before fail

    #define DEBUG

    //prototypes

    int establish_connection (const char * name, unsigned short port);

    int send_stream (int sockfd, const char * data, int len);

    unsigned long getFileSize(char *fileName);

    //check ip or dns

    int main(int argc, char *argv[])

    {

    FILE *fp;

    int j; //loop counters

    short int i; //this better be 2 bytes

    char * buffer;

    unsigned long *tmp;

    unsigned short port;

    int sockfd;

    unsigned long fileSize;


    if ((buffer = (char *) malloc (MAX_BYTES)) == NULL)

    {

    fprintf(stderr, "Not enough memory for a file input buffer of %d\n",
    MAX_BYTES);

    exit(1);

    }


    //Check if 3 arguments passed

    if (argc !=4)

    {

    fprintf(stderr, "Usage: %s <ip> <port> <file>\n", argv[0]);

    exit(1);

    }


    //no check!

    port = atoi(argv[2]);


    #ifdef DEFINE

    printf("Arguments Passed:\n");

    printf("IP: %s\n", argv[1]);

    printf("PORT: %d\n", port);

    printf("FILE: %s\n", argv[3]);

    printf("\n");

    #endif



    //open file

    if ((fp = fopen(argv[3],"r")) == NULL)

    {

    fprintf(stderr, "Error: Could not open %s\n", argv[3]);

    exit(1);

    }


    if ((sockfd = establish_connection (argv[1], port)) == -1)

    {

    fprintf(stderr, "Error establishing connection\n");

    fclose(fp);

    exit(1);

    }


    //buffer = "Hello World";

    //send_stream(sockfd, buffer, 11);


    //send file size

    fileSize = getFileSize(argv[3]);

    tmp = (unsigned long *) &buffer[0];

    *tmp = (unsigned long) htonl(fileSize);

    send_stream(sockfd, buffer, 4);

    printf("File Size: %d\n", fileSize);


    while (!feof(fp))

    {

    //read some bytes

    for (i = 0; i<MAX_BYTES; i++)

    {

    buffer[i] = fgetc(fp);

    if (feof(fp)) //end of file true

    break;

    }



    //echo bytes to screen

    for (j=0; j<i; j++)

    {

    //put send function here

    //printf("%c", buffer[j]);

    }


    if (!send_stream(sockfd, buffer, i))

    {

    fprintf(stderr, "Error sending a block\n");

    exit(1);

    }

    }


    //close file

    fclose(fp);

    close(sockfd);


    return 0; //exited succesfully

    }



    //pass name of the host and port number only!

    //-1 fail, sockfd success

    int establish_connection (const char * name, unsigned short port)

    {

    struct sockaddr_in their_addr;

    int sockfd;

    int r; //returned from functions

    struct hostent * h;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);


    //set up the structure

    their_addr.sin_family = AF_INET;

    their_addr.sin_port = htons(port); // short, network byte order

    memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct


    h=gethostbyname(name);

    if (h == NULL)

    return -1;


    //1. make *h_addr_list[0] be a in_addr *

    //2. dereference this pointer and assign it to their_addr.sin_addr

    their_addr.sin_addr = *((struct in_addr *)h->h_addr);


    printf("IP Address : %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));

    printf("IP Address : %s\n", inet_ntoa(their_addr.sin_addr));

    printf("Port: %d \n", ntohs(their_addr.sin_port));


    if((connect(sockfd, (struct sockaddr *) &their_addr, sizeof(struct
    sockaddr))) == -1)

    return -1;


    return sockfd;

    }

    //sends data

    //connect may return that it sent less, this function sends the rest

    //return 0 on fail, 1 on success

    int send_stream (int sockfd, const char * data, int len)

    {

    int bytes_sent, newlen;

    const void * newdata;


    bytes_sent = send(sockfd, data, len,0);

    if (bytes_sent < 0)

    return 0;

    while (bytes_sent < len - 1)

    {

    //if we sent 10 bytes, we sent bytes 0...9

    //need to send byte 10...

    newdata = &data[bytes_sent];

    bytes_sent = send(sockfd, newdata, len - bytes_sent, 0);

    if (bytes_sent < 0)

    return 0;

    }

    return 1;

    }

    unsigned long getFileSize(char *fileName)

    {

    unsigned long fileSize;

    FILE *f=fopen(fileName, "rb");

    if(f==NULL)

    {

    fprintf(stderr, "Cannot open file.\n");

    exit(EXIT_FAILURE);

    }

    else

    {

    if(fseek(f, 0, SEEK_END)!=0)

    {

    fprintf(stderr, "Cannot use file.\n");

    exit(EXIT_FAILURE);

    }

    fileSize=ftell(f);

    }

    if(fclose(f)!=0)

    {

    fprintf(stderr, "Cannot close file.\n");

    exit(EXIT_FAILURE);

    }

    return fileSize;

    }


    Marcia Guest

  2. #2

    Default Re: Help with Select

    Hi,

    Problem fixed! I put FD_SET, FD_CLR, select, FD_ISSET all inside the loop.

    Thanks for your help.
    Marcia


    Marcia Guest

  3. #3

    Default Re: Help with Select

    On Sat, 14 Feb 2004 15:42:52 GMT, "Marcia Hon" <com>
    wrote:

    This has nothing to do with ANSI C, so I've removed it from the
    Followup-To field. (I should probably have removed
    comp.os.linux.networking, too.)

     

    select() will destroy the "master" parameter each time you call it. So
    your code should look like this:


    saved_master = master;

    while(1){
    printf("select\n");

    master = saved_master;

    if(select(fdmax+1, &master, NULL, NULL, NULL) == -1){
    perror("select");
    exit(1);
    }


    BTW, your code is ugly indented. If the bug in your code hadn't been
    easy to spot, probably none would have taken the time to have a look
    at it.

    --
    Fernando Gont
    e-mail: gont.com.ar

    [To send a personal reply, please remove the ANTISPAM tag]
    Fernando Guest

  4. #4

    Default Re: Help with Select

    "Marcia Hon" <com> writes: 

    Select modifies its arguments. You need to put the FD_SET invocations
    *inside* the loop, or save a copy of 'master' somewhere.

    --
    James Carlson, IP Systems Group <com>
    Sun Microsystems / 1 Network Drive 71.234W Vox +1 781 442 2084
    MS UBUR02-212 / Burlington MA 01803-2757 42.497N Fax +1 781 442 1677
    James Guest

Similar Threads

  1. Replies: 4
    Last Post: April 4th, 08:21 AM
  2. Replies: 0
    Last Post: September 24th, 03:24 AM
  3. Replies: 0
    Last Post: September 11th, 11:26 AM
  4. Replies: 0
    Last Post: September 11th, 12:19 AM
  5. Replies: 0
    Last Post: April 15th, 01:22 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139