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

C UDP客户端无法从服务器接收数据,c,sockets,networking,udp,C,Sockets,Networking,Udp,我有一个UDP客户端和一个UDP服务器。程序的流程是:首先从终端执行服务器,终端创建一个套接字并绑定它,然后等待来自客户端的文件名。在另一个终端中执行客户端。这里还创建了一个套接字,并与服务器建立了连接。然后向客户端提供一个文件名。使用sendto()函数将此文件名发送到服务器。服务器能够从客户端接收文件名,并且服务器还将文件中的数据发送到客户端。但是,另一端的接收器一直在等待来自服务器的数据 UDP客户端和服务器的代码如下所示 UDP服务器: #include<sys/types.h&g

我有一个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);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
int cont,创建_套接字,新建_套接字,addrlen,fd;
int bufsize=1024;
int nameLen=0;
int client_address_size=0;
char*buffer=malloc(10);
字符fname[256];
地址中的结构sockaddr_,客户端;
如果((创建套接字=套接字(AF_INET,SOCK_DGRAM,0))>0)
printf(“已创建套接字\n”);
address.sin_family=AF_INET;
address.sin_addr.s_addr=INADDR\u ANY;
address.sin_port=htons(15000);
if(bind(create_socket,(struct sockaddr*)和address,sizeof(address))==0)
printf(“绑定套接字\n”);
nameLen=sizeof(地址);
if(getsockname(创建_套接字,(结构sockaddr*)和地址,以及nameLen)0)
{
写入(1,缓冲区,续);
}
printf(“\nEOF\n”);
返回关闭(创建_插座);
}
我哪里做错了?请提供适当的解决方案


提前谢谢。

让我写一个有效的例子。我试图重写您自己的代码,但我更愿意向您展示一个很好的示例。就几分钟

---编辑---

好的,我来了。请原谅我花了这么多时间,但我更愿意仔细阅读代码

这是您的两个文件:


真希望我能帮助你

您在
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);

非常糟糕的代码。与其打印成功案例中发生的情况而忽略失败案例,不如检查失败案例并打印
errno
strerror
或调用
peror(),
,以便了解失败。目前,任何事情都可能出错,你永远不会知道。打印诸如“接受请求”之类的内容(当您实际执行的操作被发送时)或“接受连接”之类的内容(当您所做的所有操作都是创建一个无连接套接字时)同样毫无意义。同时在所有警告都打开的情况下编译,然后修复代码。好的。。。我会很高兴有一些工作的例子。提前谢谢。如果您觉得有用,请告诉我!谢谢。。。这实际上提供了一个非常好的想法来改进我的代码,并提供了一个新的想法来创建一个更好的客户机。我在代码中遇到的一个问题是:您的代码是否可以在通过LAN连接的两台不同的机器上使用?如果可以,需要在代码中执行哪些更改?(因为我上面发布的代码只适用于同一台机器中的客户机服务器)。请回答同样的问题。对于第二个问题:服务器在收到第一条消息时获取客户端IP地址(它将客户端信息保存在客户端结构中)。然后尝试打开该文件(如果存在)。成功后,它首先发送文件长度,然后发送其内容。对于第一个问题,我可以说我只在电脑上试过我的代码,但我认为可以通过局域网来实现。如果您仍有疑问,请毫不犹豫地询问。UDP是无连接的,这意味着您不需要像TCP那样使用函数listen()、accept()和connect()。当UDP服务器绑定时,它可以从每个客户端接收数据,但不能保证所有数据都会到达目的地。这是因为IP协议(在UDP/TCP下)不保证任何安全性,UDP也不保证。我的意思是,当客户机将其文件名发送到服务器时,它会存储其地址以与客户机通信。在服务器实现中,唯一的(套接字)文件描述符是服务器的描述符。您是否在服务器端执行了任何修改?因为即使在客户机中进行了上述更改之后,我也得到了相同的输出。也就是说,客户端仍在等待接收数据。既然您提到了它,我确实删除了sendto()中第6个参数前面的
&
运算符。这是对编译器警告的自动反应,所以一开始我不记得了。就像你的问题上的其他评论所说的,代码不是很健壮,你应该仔细检查编译器警告。谢谢它的工作。。。还有一件事。。。在收到所有数据后,客户端仍在等待
sendto(create_socket,buffer,cont,0,(struct sockaddr *) &client,client_address_size);