0

我对 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

4

2 回答 2

1

正如您所注意到的,UDP 中没有“连接”的概念——即使你调用了——所以当通信结束时connect(2)没有办法read返回。0有一些方法可以解决这个问题:

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

这两种方法在实践中都有点脆弱:想象一下如果“输出结束”消息变得很多会发生什么。因此,您还必须针对这种情况进行准备,并可能添加超时(SO_RCVTIMEO例如查找)。

于 2013-04-10T19:34:34.800 回答
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;


                }
于 2013-04-10T20:21:18.537 回答