zak
zak

Reputation: 104

return from read in connected udp sockets in c

i programming UDP client/Server model and the main functionaly for this app is client insert the directory path then the server will retrun the contents of supplied directory to the client, so this Client code :

#include "cliHeader_UDP.h"

int
main(int argc, char **argv)
{
    int                 sockfd;
    struct sockaddr_in  servaddr;

        /*Error checking for providing  appropirate port# */
    if(argc<3 )  
        err_quit("Error,no port provided, please enter the port#:22011 \n");

    portno=atoi(argv[2]);


    for(;;)
    {
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(portno);
        Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

        sockfd = Socket(AF_INET, SOCK_DGRAM, 0);        
        dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
    }
    exit(0);
}

**//and here is the dg_cli implemntation :**


void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
    int n;
    char    sendline[MAXLINE], recvline[MAXLINE + 1];

    Connect(sockfd, (SA *) pservaddr, servlen);
    for(;;)
    {
         bzero(&sendline, sizeof(sendline));
         printf("please enter Directory Name :\n");
         Fgets(sendline, MAXLINE, fp);

        /*To check if the supplied name ended with \n in sendline buffer */
        if((p = strchr(sendline, '\n'))) *p = 0; 

        write(sockfd, sendline, strlen(sendline));
        printf("test for write\n");                     
**Line 31.......:**     while ( (n=read(sockfd, recvline, MAXLINE)) )
                {
                    if(n<0)
                    perror("Error");

                    printf("recvline is: %s\n",recvline);
                    printf("n========%d\n",n);



                }
            printf("exit from read While\n");
            recvline[n] = 0;    /* null terminate */



    }
}

the problem in Line 31... is the 1st time run as i wanted client insert DIR path so the server will return the contents of the path ,but when the user need to insert again the path ,its still blocking in read in the for loop and does not return from for loop , so how to put condtion when the contents of buffer ended return from for loop like EOF in TCP

Upvotes: 0

Views: 366

Answers (2)

zak
zak

Reputation: 104

i tried some thing like that have a look : part of code at server side:

//at server side Read the directory contents
            printf("The contents of [%s] is :\n",mesg);
            bzero(&mesg, sizeof(mesg));
            while( (dptr = readdir(dp)) !=NULL ) 
            {
                printf(" \n[%s] \t",dptr->d_name);
                //report(dptr->d_name, &status_buf);
                sprintf(mesg,"%s",dptr->d_name);

                if((dptr = readdir(dp)) ==NULL)     
                {
                    bzero(&mesg, sizeof(mesg));
                    sprintf(mesg,"%c",'!');
                    Sendto(sockfd, mesg, sizeof(mesg), 0, pcliaddr, len);
                }

                Sendto(sockfd, mesg, sizeof(mesg), 0, pcliaddr, len);

            }
            // Close the directory stream
            closedir(dp);


//and at the client side : 

flag=1;             
        while ( (n=read(sockfd, recvline, MAXLINE)) )
                {
                    if(n<0)
                    perror("Error");

                    printf("recvline is: %s\n",recvline);
                    flag=flag+1;
                    printf("Flag now is :%d\n",flag);
                    printf("n========%d\n",n);
                         bzero(&recvline, sizeof(recvline));
                    if(recvline[0]=='!')
                        return;


                }

Upvotes: 0

cnicutar
cnicutar

Reputation: 182684

As you noticed there's no concept of "connection" in UDP - even if you called connect(2) - so there's no way for read to return 0 when the communication is over. There are ways to fix this:

  • Have the server send a 0-length message when the output is over or some other special marker
  • Have the client analyze the input and somehow detect it is over

Both these methods are a little bit fragile in practice: imagine what happens if the "output is over" message gets lots. So you'll also have to provision for that case and maybe add a timeout (look for SO_RCVTIMEO for example).

Upvotes: 1

Related Questions