从读取连接的udp套接字返回c

时间:2013-04-10 19:28:38

标签: c sockets unix blocking udpclient

我编写UDP客户端/服务器模型,这个应用程序的主要功能是客户端插入目录路径然后服务器将所提供的目录的内容重新回到客户端,所以这个客户端代码:

#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 */



    }
}

第31行中的问题...是第一次运行,因为我希望客户端插入DIR路径,因此服务器将返回路径的内容,但是当用户需要再次插入路径时,它仍然在for循环中阻塞读取并且不从for循环返回, 那么如何在缓冲区的内容结束时从for循环返回就像TCP中的EOF那样放置condtion

2 个答案:

答案 0 :(得分:1)

正如您所注意到的,UDP中没有“连接”的概念 - 即使您呼叫connect(2) - 因此当通信结束时{} 1}无法返回read。有办法解决这个问题:

  • 当输出结束或其他特殊标记
  • 时,让服务器发送0长度的消息
  • 让客户分析输入并以某种方式检测它已结束

这两种方法在实践中都有点脆弱:想象一下,如果“输出结束”消息有很多,会发生什么。因此,您还必须为该案例进行规定,并可能添加超时(例如,查找0)。

答案 1 :(得分:0)

我尝试过这样的东西看看: 服务器端代码的一部分:

//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;


                }