2014-09-03 108 views
0

我正在使用标准方式(在许多示例中显示)在C++中创建一个UDP套接字,使其保持活动状态并不断发送信息。在没有套接字监听的情况下创建UDP客户套接字

我只打电话sendto。我从来没有打电话给recvfrom。在此代码片段中,我只用一次sendto,然后睡5秒:

C代码:

static int do_the_rest(int sock) 
{ 
    struct sockaddr_in server_addr; 

    bzero(&server_addr,sizeof(server_addr)); 
    server_addr.sin_family = AF_INET; 
    server_addr.sin_addr.s_addr=inet_addr("192.168.32.32"); 
    server_addr.sin_port=htons(32000); 

    char sendline[100]; 
    bzero(sendline,sizeof(sendline)); 

    const struct sockaddr * addr = (const struct sockaddr*)&server_addr; 

    sendto(sock,sendline,sizeof(sendline),0,addr,sizeof(server_addr)); 

    sleep(5); 

    return 0; 
} 

int main(int argc, char**argv) 
{ 
    int sock; 

    sock=socket(AF_INET,SOCK_DGRAM,0); 
    if(sock < 0) { 
     perror("socket"); 
     return 1; 
    } 

    int ret = do_the_rest(sock); 
    close(sock); 

    return ret; 
} 

现在,如果我运行“netstat的-na”,我可以识别系统似乎听插座(我删除我的程序打印本地端口的线,为清楚起见)的本地端口:

的netstat -na:

Active Internet connections (servers and established) 
Proto Recv-Q Send-Q Local Address    Foreign Address    State 
... 
udp  0 304 0.0.0.0:53735    0.0.0.0:* 

当我试图在Java中类似的东西,我也似乎得到一些听力,虽然看起来有点不同(或许IPv6的?):

Java代码:

import java.io.*; 
import java.net.*; 

class Udp { 
    public static void main(String[] args) throws Throwable { 
     DatagramSocket sock = new DatagramSocket(null); 

     try { 
      InetAddress ipAddress = InetAddress.getByName("192.168.32.32"); 

      byte[] sendData = new byte[50000]; 

      DatagramPacket sendPacket = new DatagramPacket(
       sendData, sendData.length, ipAddress, 32000); 

      sock.send(sendPacket); 

      Thread.sleep(5000); 

     } finally { 

      sock.close(); 
     } 
    } 
} 

的netstat -na:

Active Internet connections (servers and established) 
Proto Recv-Q Send-Q Local Address    Foreign Address    State 
... 
udp  0  0 :::37053     :::* 

我明白这是为了支持做了可能recvfrom(0 Java中的)。但是,有没有办法告诉套接字根本不听进来的数据包?

感谢

回答

1

现在,如果我运行“netstat的-na”,我可以识别系统似乎插座的本地端口上侦听

UDP套接字有一个内核缓冲区收到消息。无论您是否从用户空间代码调用recv/recvfrom/recvmsg,此缓冲区都由内核维护。

1

您可以使用shutdown()how参数设置为SHUT_RD禁用读取插座上,可能有停止听,甚至释放的接收缓冲区内核的预期行为。但是接收端口必须保持为套接字的生命周期分配,因为它用作与sendto()一起发送的传出数据包的源端口。你无法避免这种情况。

+0

谢谢,虽然shutdown()没有帮助。我认为它可能只对TCP套接字有影响。 – Nadav 2014-09-03 21:37:26

0

它不仅在该端口上“侦听”,而且还在上通过该端口发送。端口分配是必需的。只要调用sendto(),套接字就会绑定到端口,除非它已经绑定。