简体   繁体   English

UDP客户端无法从服务器接收数据

[英]UDP client unable to receive data from the server

I have a UDP client and a UDP server. 我有一个UDP客户端和一个UDP服务器。 The flow of the program is: first the server is executed from the terminal, the terminal creates a socket and binds it and waits for a filename from the client. 程序的流程是:首先从终端执行服务器,终端创建套接字并绑定它并等待来自客户端的文件名。 In another terminal the client is executed. 在另一个终端中执行客户端。 Here also a socket is created, and a connection is established with the server. 这里还创建了一个套接字,并与服务器建立了连接。 Then a filename is provided to the client. 然后向客户端提供文件名。 This filename is sent to the server using sendto() function. 使用sendto()函数将此文件名发送到服务器。 The server is able to receive filename from the client and the server is also sending the data in the file to the client. 服务器能够从客户端接收文件名,服务器也将文件中的数据发送到客户端。 However the receiver on the other side keeps waiting for the data from the server. 但是,另一方的接收器一直在等待来自服务器的数据。

The code for the UDP client and server is as shown below. UDP客户端和服务器的代码如下所示。

UDP Server: 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 Client: 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);
}

Where am i going wrong? 我哪里错了? Please provide a proper solution for the same. 请为此提供适当的解决方案。

Thanks in advance. 提前致谢。

You are using the value-result arguments in recvfrom() wrong. 您正在使用recvfrom()的value-result参数错误。 A compiler should warn you about this very loudly. 编译器应该非常大声地警告你。 Recvfrom() will try to return a number to you in the 6th parameter, so you can not pass it a constant created with sizeof() . Recvfrom()将尝试在第6个参数中为您返回一个数字,因此您无法将其传递给使用sizeof()创建的常量。

From the manpage: 从联机帮助页:

The argument addrlen is a value-result argument, which the caller should initialize before the call to the size of the buffer associated with src_addr, and modified on return to indicate the actual size of the source address. 参数addrlen是一个value-result参数,调用者应该在调用与src_addr关联的缓冲区大小之前初始化,并在返回时修改以指示源地址的实际大小。

I changed the recvfrom() loop like this and a file was successfully sent & received. 我改变了这样的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);
}

Since you are calling connect() on the socket, you could also use recv() , like so: 既然你在套接字上调用connect(),你也可以使用recv() ,如下所示:

recv(create_socket, buffer, 10, 0)

As some general advice, allways carefully check the return values from system and library calls (except maybe for printf() ) and be prepared for all cases listed on the functions man-page under "return values". 作为一些一般性建议,总是仔细检查系统和库调用的返回值(可能除了printf() ),并为“返回值”下的函数手册页中列出的所有情况做好准备。

EDIT The server side makes a similar error in the other direction. 编辑服务器端在另一个方向上产生类似的错误。 A parameter of sendto() that should just be the length of the passed struct, is passed as a pointer. sendto()参数应该只是传递的结构的长度,作为指针传递。

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

Should be 应该

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

Just let me to write a valid example. 让我写一个有效的例子。 I've tried to rewrite your own code, but I prefer to show you a nice example. 我试图重写你自己的代码,但我更喜欢向你展示一个很好的例子。 Just a few minutes... 只需几分钟......

---EDIT--- - -编辑 - -

Ok, here I am. 好的,我在这里。 Forgive me for the time I spent, but I preferred to read carefully the code. 原谅我花了我的时间,但我更愿意仔细阅读代码。

Here your two files: 这是你的两个文件:

Server implementation 服务器实现

Client implementation 客户实施

Really hope I helped you. 真的希望我能帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM