0

UDPクライアントとUDPサーバーがあります。プログラムのフローは次のとおりです。最初にサーバーが端末から実行され、端末がソケットを作成してバインドし、クライアントからのファイル名を待ちます。別の端末でクライアントが実行されます。ここでもソケットが作成され、サーバーとの接続が確立されます。次に、ファイル名がクライアントに提供されます。このファイル名は、sendto()関数を使用してサーバーに送信されます。サーバーはクライアントからファイル名を受信でき、サーバーはファイル内のデータもクライアントに送信しています。ただし、反対側の受信者はサーバーからのデータを待ち続けます。

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);
}

どこが間違っているのですか?同じための適切な解決策を提供してください。

前もって感謝します。

4

2 に答える 2

2

value-result引数を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);
于 2013-03-14T09:00:59.093 に答える
0

有効な例を書かせてください。私はあなた自身のコードを書き直そうとしました、しかし私はあなたに良い例を示すことを好みます。ほんの数分...

- -編集 - -

はい、ここにいます。私が費やした時間は許してください、しかし私はコードを注意深く読むことを好みました。

ここにあなたの2つのファイルがあります:

サーバーの実装

クライアントの実装

私があなたを助けたことを本当に願っています。

于 2013-03-14T08:55:20.873 に答える