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

标签 c sockets networking udp

我有一个 UDP 客户端和一个 UDP 服务器。程序的流程是:首先从终端执行服务器,终端创建一个套接字并绑定(bind)它,并等待来自客户端的文件名。在另一个终端中执行客户端。这里还创建了一个套接字,并与服务器建立了连接。然后将文件名提供给客户端。该文件名使用 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);
}

我哪里出错了?请提供适当的解决方案。

提前致谢。

最佳答案

您在 recvfrom() 中使用了错误的值结果参数。编译器应该非常大声地警告你这一点。 Recvfrom() 将尝试在第 6 个参数中返回一个数字,因此您不能向其传递使用 sizeof() 创建的常量。

来自联机帮助页:

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.

我像这样更改了 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() 除外),并为函数手册页“return”下列出的所有情况做好准备值(value)观”。

编辑 服务器端在另一个方向上会出现类似的错误。 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);

关于c - UDP客户端无法从服务器接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15403206/

相关文章:

javascript - 为什么关闭 Charles 应用程序后无法访问网站?

c - 为什么这段代码运行时会崩溃?

c++ - Eclipse-PDT:更改包含文件夹

sockets - 如何在多宿主服务器的非默认接口(interface)上接收多播数据

c# - 关闭断开的异步套接字会使监听器停止监听吗?

Android - 这是发送单个 UDP 数据包的正确方法吗?

ios - 为什么在处理 web API 时需要异步返回数据?

c++ - C++ 函数如何返回大对象或结构?

c - TeamCity 中没有构建失败

c# - 如何确定连接的套接字是否使用 IPSec?