当前位置: 首页 > 知识库问答 >
问题:

如何使用相同的UDP套接字发送和接收数据包?我在这段代码中遗漏了什么?

万俟小林
2023-03-14

我正在尝试编写一个应用程序,其中客户端应该将UDP数据包发送到服务器,然后服务器应该回复客户端,全部通过无线接口。客户端和服务器都在同一个二进制文件中实现,用户可以使用适当的命令行参数选择模式。

我使用的是UDP,但我有问题使客户端和服务器通信。首先,我试图使用相同的UDP套接字来接收和发送数据包,在这两种情况下。我想这是可能的,但我开始有些怀疑了。

然后,这是客户端和服务器端的相关代码:

        struct sockaddr_in inaddr;

        fd=socket(AF_INET,SOCK_DGRAM,0);

        if(fd==-1) {
            perror("socket() error");
            exit(EXIT_FAILURE);
        }

        // Prepare sockaddr_in structure
        bzero(&inaddr,sizeof(inaddr));
        inaddr.sin_family=AF_INET;
        inaddr.sin_port=htons(opts.port); // opts.port is parsed from the command line
        inaddr.sin_addr.s_addr=opts.destIPaddr.s_addr; // opts.destIPaddr is parsed from the command line and already in the correct format

        // Bind to the wireless interface (devname is previusly obtained in a tested piece of code)
        if(setsockopt(sData.descriptor,SOL_SOCKET,SO_BINDTODEVICE,devname,strlen(devname))==-1) {
            perror("setsockopt() for SO_BINDTODEVICE error");
            close(sData.descriptor);
            exit(EXIT_FAILURE);
        }
sendto(fd,packet,packetsize,0,(struct sockaddr *)&(inaddr),sizeof(inaddr))
struct sockaddr_in srcAddr;
socklen_t srcAddrLen=sizeof(srcAddr);

// .....

recvfrom(fd,packet,MAX_PACKET_SIZE,0,(struct sockaddr *)&srcAddr,&srcAddrLen);
  • 将套接字绑定到客户端和服务器端的特定端口,即客户端应将指定端口作为目的地发送数据包,而服务器应完全在同一端口侦听接收数据包
  • 仅将套接字绑定到无线接口(其名称目前存储在devname中,但获取其IP地址或MAC地址也不成问题)
  • 使服务器和客户端通过UDP通信,客户端发送请求,服务器接收请求并回复客户端,客户端应接收所有回复

共有1个答案

樊运乾
2023-03-14

虽然从问题本身来看并不清楚,但您的注释似乎表明您并不像@SomeProgrammerDude所推断的那样bind()将地址发送到套接字。在这种情况下,必须理解bind()ing与SO_BindToDevice套接字选项所起的作用是不同的,而且很大程度上是正交的,尽管在选项名称中使用了“bind”。

bind()函数是关于将套接字与地址相关联的,对于TCP和UDP,该地址包含端口号。so_bindtodevice将套接字限制为通过特定设备的数据。虽然在实践中,IP地址和网络接口之间通常存在一对一的映射,

>

  • POSIX系统接口不是IP协议簇特有的,它们注意避免假定地址族都具有与IP相似的特性。

    即使对于IP,一个网络接口也有可能具有多个地址。

    特别是对于IP,在任何情况下,您都需要将套接字与端口相关联,系统才会接受该端口的入站流量。socket选项不会这样做,它甚至不会直接将套接字与IP地址相关联。这就是bind()的作用。

    在你询问的评论中

  •  类似资料:
    • 我想使用Qt UDP(不是TCP)套接字传输文件。所以我这样写代码: 看来要传输的Qt UDP数据包的最小大小是8192字节。接收方总是得到第一个数据包,但不能接收其他数据包。 我对Qt和网络编程的经验很少,所以我不知道我的猜想对不对。你能告诉我如何改变这些代码来支持在第一个数据包之后接收数据包,这样我就可以传输大数据了吗?

    • 问题内容: 我正在使用套接字连接我的Android应用程序(客户端)和Java后端服务器。每次与服务器通信时,我都希望从客户端发送两个数据变量。 1)某种消息(由用户通过界面定义) 2)消息的语言(由用户通过界面定义) 我该如何发送这些消息,以便服务器将每个消息解释为一个单独的实体? 在读取了服务器端的数据并做出了适当的结论之后,我想向客户端返回一条消息。(我想我会没事的) 因此,我的两个问题是如

    • 由于某种原因,我很难从同一套接字发送和接收数据。无论如何,这是我的客户端代码: 基本上,我想创建一个协议,我发送一个udp包,然后我期待一个响应。就像HTTP协议一样,每个请求都有一个响应。如果服务器在不同的计算机上,此代码可以工作。但是,可能会出现服务器和客户端在同一台计算机上的情况。 以下是服务器: 我不能使用tcp的原因是因为有时客户端在NAT(路由器)后面,并且做UDP打孔比TCP更简单。

    • 如何将数据从PHP页面发送到TCP端口? 我正在使用它,但我不能使用任何数据!还有,你知道我怎么才能暂停吗? 有什么问题?

    • 一个非常简单的服务器代码: 还有一个简单的客户端,可以从这个套接字读取数据: 我正在尝试的是非常高层次的,实际上也非常简单。sock.getOutputStream如何连接到s.getInputStream()? 如何通过客户端输出流发送的数据可以从服务器输入流中读取?我无法在头脑中建立联系,也无法想象它。 我的问题是inputstream和outputstream对象是如何连接的?我怎么能成为一