2013-03-14 107 views
0

我有一個UDP客戶端和一個UDP服務器。程序的流程是:首先從終端執行服務器,終端創建一個套接字並綁定它並等待客戶端的文件名。在另一個終端中執行客戶端。這裏也創建一個套接字,並與服務器建立連接。然後給客戶端提供一個文件名。這個文件名使用sendto()函數發送到服務器。服務器能夠從客戶端接收文件名,服務器也將文件中的數據發送到客戶端。但是另一端的接收機一直在等待來自服務器的數據。UDP客戶端無法從服務器接收數據

UDP客戶端和服務器的代碼如下所示。

UDP服務器:

#include<sys/types.h> 
#include<sys/socket.h> 
#include<netinet/in.h> 
#include<sys/stat.h> 
#include<unistd.h> 
#include<stdlib.h> 
#include<stdio.h> 
#include<fcntl.h> 
int main() 
{ 
    int cont,create_socket,new_socket,addrlen,fd; 
    int bufsize = 1024; 
    int nameLen=0; 
    int client_address_size=0; 
    char *buffer = malloc(10); 
    char fname[256]; 
    struct sockaddr_in address,client; 

    if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) > 0) 
    printf("The socket was created\n"); 

    address.sin_family = AF_INET; 
    address.sin_addr.s_addr = INADDR_ANY; 
    address.sin_port = htons(15000); 

    if (bind(create_socket,(struct sockaddr *)&address,sizeof(address))== 0) 
     printf("Binding Socket\n"); 

    nameLen=sizeof(address); 

    if (getsockname(create_socket,(struct sockaddr *)&address,&nameLen)<0) 
    { 
     printf("\n\ngetsockname() error\n"); 
     exit(3); 
    } 

    printf("Port assigned is %d\n", ntohs(address.sin_port)); 

    client_address_size=sizeof(client); 

    if(recvfrom(create_socket,fname, 255,0,(struct sockaddr *) &client,&client_address_size)<0) 
    { 
     printf("\n\nrecvfrom() failed\n"); 
     exit(4); 
    } 

    printf("A request for filename %s Received..\n", fname); 

    if ((fd=open(fname, O_RDONLY))<0) 
    { 
     perror("File Open Failed"); 
     exit(0); 
    } 

    while((cont=read(fd, buffer, 10))>0) 
    { 
     //sleep(1); 
     sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,&client_address_size); 
     printf("\n\nPacket sent\n"); 
    } 

    printf("Request Completed\n"); 

    return close(create_socket); 
} 

UDP客戶:

#include<sys/socket.h> 
#include<sys/types.h> 
#include<netinet/in.h> 
#include<unistd.h> 
#include<stdlib.h> 
#include<stdio.h> 

int main() 
{ 
    int create_socket,cont; 
    char *arg="127.0.0.1"; 
    int bufsize = 1024; 
    int server_address_size=0; 
    char *buffer = malloc(10); 
    char fname[256]; 
    struct sockaddr_in address,server; 

    if ((create_socket = socket(AF_INET,SOCK_DGRAM,0)) > 0) 
     printf("The Socket was created\n"); 

    address.sin_family = AF_INET; 
    address.sin_port = htons(15000); 
    address.sin_addr.s_addr=inet_addr(arg); 

    if (connect(create_socket,(struct sockaddr *) &address,sizeof(address)) == 0) 
     printf("The connection was accepted with the server %s...\n",arg); 

    printf("Enter The Filename to Request : "); 
    scanf("%s",fname); 
    sendto(create_socket, fname, sizeof(fname), 0,(struct sockaddr *) &address,sizeof(address)); 
    printf("Request Accepted... Receiving File...\n\n"); 

    server_address_size=sizeof(server); 


    printf("The contents of file are...\n\n"); 

    while((cont=recvfrom(create_socket, buffer, 10, 0,(struct sockaddr *) &address,sizeof(address)))>0) 
    { 
     write(1, buffer, cont); 
    } 

    printf("\nEOF\n"); 
    return close(create_socket); 
} 

我在哪裏去了?請爲此提供適當的解決方案。

在此先感謝。

+0

很差代碼。與其打印在成功案例中發生的情況而忽略失敗案例,您最好建議檢查失敗案例並打印errno或strerror或調用perror(),以便了解故障。目前什麼都可能會出錯,你永遠不會知道。當你實際做了什麼被髮送了什麼,或者當你所做的所有事情都被創建了無連接套接字時,「接受連接」都被打印出來,就像'請求接受'一樣。 – EJP 2013-03-14 07:49:17

+0

也編譯所有waring,然後修復代碼。 – alk 2013-03-14 07:53:36

回答

2

您正在使用recvfrom()中的值結果參數錯誤。編譯器應該非常大聲地警告你。 Recvfrom()將嘗試在第6個參數中向您返回一個數字,因此您無法將其傳遞給使用sizeof()創建的常量。

從手冊頁:

的參數addrlen中是 值結果參數,其中所述呼叫者應該呼叫到 大小與SRC_ADDR相關聯的緩衝器的前初始化,和改性的上返回,以指示 源地址的實際大小。

我改變了這樣的recvfrom()循環,併成功發送文件&收到。

int serv_addr_size = sizeof(address); 
while((cont=recvfrom(create_socket, buffer, 10, 0,(struct sockaddr *) &address,&serv_addr_size))>0) 
{ 
    write(1, buffer, cont); 
} 

既然你調用connect()套接字上,你也可以使用recv(),就像這樣:

recv(create_socket, buffer, 10, 0) 

由於一些一般性的建議,八方通小心地從系統和庫調用檢查返回值(可能爲printf()除外),併爲「返回值」下的功能手冊頁中列出的所有情況做好準備。

編輯服務器端在另一個方向上發生類似的錯誤。參數sendto()應該只是傳遞的結構的長度,作爲指針傳遞。

sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,&client_address_size); 

應該

sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,client_address_size); 
+0

感謝您的答覆...我會檢查輸出並接受你的答案.. – Zax 2013-03-14 09:16:37

+0

你在服務器端做過任何修改嗎? Coz即使在客戶端發生上述變化之後,我也會得到相同的輸出結果。即客戶端仍在等待數據被接收。 – Zax 2013-03-14 09:21:28

+0

現在你已經提到它了,我沒有去掉sendto()中第6個參數的&&操作符infront。這是編譯器警告的自動反射,所以我起初不記得它。就像你的問題上的其他評論所說,代碼不是很健壯,你應該仔細檢查編譯器警告。 – thuovila 2013-03-14 09:27:12

0

讓我寫一個有效的例子。我試圖重寫自己的代碼,但我更願意向您展示一個很好的示例。短短几分鐘...

---編輯---

好吧,我在這裏。原諒我花了我的時間,但我更願意仔細閱讀代碼。

這裏您的兩個文件:

Server implementation

Client implementation

真希望我幫你。

+0

好的...我會很高興有一些工作的例子。提前致謝。 – Zax 2013-03-14 09:15:12

+0

感謝您的支持...... +1爲您的努力... – Zax 2013-03-14 11:03:54

+1

讓我知道如果你發現它有用! – none 2013-03-14 11:50:10

相關問題