2013-04-10 112 views
0

我編程的UDP客戶端/服務器模型,並且此應用程序的主要功能是客戶端插入目錄路徑,那麼服務器將重新提供所提供的目錄的內容給客戶端,所以此客戶端代碼:從讀取連接的udp套接字返回c

#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循環中返回時返回condtion如TCP中的EOF那樣返回

回答

1

正如你注意到的那樣,在UDP中沒有「連接」的概念 - 即使你調用了connect(2) - 所以當通信結束時read沒有辦法返回0。有辦法解決這個問題:

  • 已在服務器當輸出超過或其他一些特殊標記
  • 在客戶端分析輸入,並以某種方式檢測到它是發送一個長度爲0的消息在

這兩種方法在實踐中都有些脆弱:想象一下,如果「輸出結束」消息得到了很多,會發生什麼。因此,您還必須爲該情況進行調配,並可能會添加超時(例如,請查找SO_RCVTIMEO)。

+0

日Thnx先進。但我知道已經沒有連接在UDP它只是我用它來運行異步錯誤,所以在我的情況下如何使客戶端分析數據,並檢測到發送數據的結束????? – zak 2013-04-10 19:43:12

+0

@ user2103930我不確定我明白你在問什麼。 – cnicutar 2013-04-10 20:01:07

+0

你說過「讓客戶分析輸入,並以某種方式檢測它已經結束」如何做到這一點,我已經嘗試過國旗,for循環,....等,但沒有成功與我也許你是在那經驗,並告訴我提示os smthin like that ... – zak 2013-04-10 20:14:01

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; 


       }