?
Solved

dont understandhow to use select in udpserver

Posted on 2005-03-19
14
Medium Priority
?
261 Views
Last Modified: 2010-04-15
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;
                    }
                }
            }
        }
    }
}
0
Comment
Question by:cranium2003
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 2
14 Comments
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 13585515
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
0
 

Author Comment

by:cranium2003
ID: 13586519
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
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 13586609

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
      }
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:cranium2003
ID: 13586700
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;
                    }
       
0
 
LVL 4

Expert Comment

by:booki
ID: 13596890
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.
0
 

Author Comment

by:cranium2003
ID: 13599611
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??
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 13600450

Create a TCP connection, (SOCK_STREAM).  

Kent
0
 

Author Comment

by:cranium2003
ID: 13600499

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
     
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 13600603

>> 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
0
 

Author Comment

by:cranium2003
ID: 13600711
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?
0
 
LVL 46

Accepted Solution

by:
Kent Olsen earned 200 total points
ID: 13600775

>>That mean i am free to write either end server or client.

In general, yes.  But rememeber that it is usually the client that initiates the connection!

And it's perfectly OK for a system to be running one application as a client and another as a server.  Think about your mail server, database server, file server, etc.  All of these systems are running applications as servers.  Yet you can still fire up a Web Browser (client) and surf the web.  As long as the applications are communicating on different ports you can have nearly any mix of clients and servers on the same box.


>>Then i have to use TCP sockets or UDP is ok

TCP.
0
 

Author Comment

by:cranium2003
ID: 13600883
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?
0
 
LVL 4

Expert Comment

by:booki
ID: 13605384
> 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.
0
 

Author Comment

by:cranium2003
ID: 13610884

      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.
         
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
Suggested Courses

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question