Link to home
Start Free TrialLog in
Avatar of cranium2003
cranium2003

asked on

dont understandhow to use select in udpserver

Hello all experts,
 i am unable to use select in my udpserver program that sends string "sendtext" to clients and clients (udpclient.c)back to server.
        Please help me to make following program as UDPSERVER which is actually TCPSERVER program with select call used.

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#define LOCAL_SERVER_PORT 9200

int main()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;
    int result;
    fd_set readfds, testfds;
    unsigned char msg[1024],recvtext[1024],sendtext[1024];
    struct timeval timeout;
    strcpy(sendtext,"mystring");


    server_sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port = htons(1500);
    server_len = sizeof(server_address);

    bind(server_sockfd, (struct sockaddr *)&server_address, server_len);


    listen(server_sockfd, 5);

    FD_ZERO(&readfds);
    FD_SET(server_sockfd, &readfds);


    while(1) {
       
        int fd;
        int nread;
        int  rc, n;
        timeout.tv_sec = 5;
        timeout.tv_usec = 000000;

        testfds = readfds;

        printf("server waiting\n");
        result = select(FD_SETSIZE, &testfds, (fd_set *)0,
            (fd_set *)0, &timeout);

        if(result < 1) {
            perror("server5");
            exit(1);
        }


        for(fd = 0; fd < FD_SETSIZE; fd++) {
            if(FD_ISSET(fd,&testfds)) {


                if(fd == server_sockfd) {
                    client_len = sizeof(client_address);
                    client_sockfd = accept(server_sockfd,
                        (struct sockaddr *)&client_address, &client_len);
                    FD_SET(client_sockfd, &readfds);
                    printf("adding client on fd %d\n", client_sockfd);
                }

                else {
                    ioctl(fd, FIONREAD, &nread);

                    if(nread == 0) {
                        close(fd);
                        FD_CLR(fd, &readfds);
                        printf("removing client on fd %d\n", fd);
                    }

                    else {
      sendagain:
rc = sendto(fd,sendtext, strlen(sendtext)+1, 0,(struct sockaddr *) &server_address, sizeof(server_address));

if(rc<0) {
printf("cannot send data \n");
close(fd);
exit(1);
}
memset(msg,0x0,1024);
client_len = sizeof(client_address);
n = recvfrom(fd, recvtext, 1024, 0, (struct sockaddr *) &client_address, &client_len);
if(strcmp(senttext,recvtext)!=0)
goto sendagain;
                    }
                }
            }
        }
    }
}
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image

Hi cranium2003,

  select () simply allows a single thread or task to manage multiple connections.  Call select () to identify which connection you're going to query, read, or write.

        select (Socket, &readFds, NULL, &exceptFds, &timeout);



Good Luck!
Kent
Avatar of cranium2003
cranium2003

ASKER

Hello Kdo,
           So i have to use
 select (Socket, &readFds, NULL, &exceptFds, &timeout);
in udpserver program. Will you please give me some small example or modification to my program pleaseeeee

You need to do two things:

1)  Every time you accept a connection (with the accept() API), record the Connection ID in an array.
2)  To scan all of the connections, select() an item in the array and query it.  Then move to the next item in the array.

      select (Socket[idx], &readFds, NULL, &exceptFds, &timeout);
      if (FD_ISSET (Port->Socket, &readFds))
      {
        i = recv (Port->Socket, data, 1, 0);   // Accept one byte
        if (i == 1)
        {
          return (data);
        }
        else
          ClosePort (Port, "Recv Error");     // We couldn't receive the byte that was there.  Close the port and continue
      }
Hello Kdo,
        But as i know udp sockets(SOCK_DGRAM) does not use accept call(DO correct me if i am wrong?) I am doing this on linux os.
       In udp  sockets there is only recvfrom and sendto thats what i face problem when i try to convert TCP socket program with select call used.
       at where i use select in SOCK_DGRAM sockets.
If i have udpsocket with its main part then where can i implement select?
while(1) {
       
        int fd;
        int nread;
        int  rc, n;
       
      sendagain:
rc = sendto(fd,sendtext, strlen(sendtext)+1, 0,(struct sockaddr *) &server_address, sizeof(server_address));

if(rc<0) {
printf("cannot send data \n");
close(fd);
exit(1);
}
memset(msg,0x0,1024);
client_len = sizeof(client_address);
n = recvfrom(fd, recvtext, 1024, 0, (struct sockaddr *) &client_address, &client_len);
if(strcmp(senttext,recvtext)!=0)
goto sendagain;
                    }
       
cranium2003,

UDP is connectionless.  The server has no way of knowing when a client "connects" to the server.  The client, therefore, must send some sort of message to initiate the conversation.  In your current design, the server first sends the string "sendtext" to the client but the server has no way of knowing which if any client is waiting for the message.

b.
If my design is wrong then how can i design a communication that have
1)PC1 generate string then send it to another PC2
2) PC2 will reaceive it print it and send back same to originating PC1
3) originating PC1 will receive and check if sent string is same as that of received if not immediately sent same string again.
       Now how can i design? Which should be server PC1 or PC2??

Create a TCP connection, (SOCK_STREAM).  

Kent

hello kent,
        but which must be client PC and which must be server PC? I want this behaviour to be used vice versa between PC1 and PC2 that i am going to utilize to write some application.
       AS i want every PC on LAN to have above communication then it will create big no. of TCP connetions. Is that harmful to network traffic?
        Thats why i decide to have UDP sockets
     

>> but which must be client PC and which must be server PC? I want this behaviour to be used vice versa between PC1 and PC2 that i am going to utilize to

You are free to declare either end the server or client.  Communications are bi-directional so either end can send data to the other.  The protocol (handshake) is up to you, too.  However, you've already stated that you'll have one system (PC) that will communicate with many systems (PCs), so that one should be your server.

>>AS i want every PC on LAN to have above communication then it will create big no. of TCP connetions. Is that harmful to network traffic?

"Network Traffic" is defined as actual communicates up and down the wire.  Open and idle connections have little or no impact.

Kent
hello Kent,
          That mean i am free to write either end server or client. Now the main thing is that as every computer has server as well as client programs and clients on each system will  send strings at particular time depending on its time at which its up.
 Say pc1 has server running and pc2 sends its string to pc1 when its statred. Then by 10 min pc3 started then it will immedialtely send its string. Then both pc2 and pc3 will send strings at interval say 5 minuntes to pc1
         Then i have to use TCP sockets or UDP is ok?? Does this creates any time problem by allowing other pcs to wait by server? That mean whether server require SELECT() call to handle multiple clients or not?
ASKER CERTIFIED SOLUTION
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hello Kdo,
           THNAKS A LOT FOR THAT VALUABLE INFO. BUT,
         Pleaseee,
           My original question remians require me to know whether select is required or not in my scenario given in my last post. and also whether select can be used with udp sockets or not?? Your First reply to me says its allowed.
       Please i require now only this info in this question?
> whether select is required or not in my scenario given in my last post.

No.  You probably don't need to use select() since you're only waiting for messages on one UDP port.  If you were "listening" on multiple UDP ports you would want to use select().

> select can be used with udp sockets or not??

select() can be used with UDP.

b.

      Hello booki,
>       If you were "listening" on multiple UDP ports you would want to use select().
        So what i understood from this thread is that Select can be used with TCP as well as UDP.
         To listen on any port from single program(Is that possible how??) require to use select.
         select also not required when i want to receive data from any client on same server port and only to be used at server side not client side.
          Please correct me.