我使用标准方法(如许多示例所示)在C ++中创建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;
}
现在,如果我运行&#34; netstat -na&#34;,我可以确定系统似乎在套接字的本地端口上侦听(我删除了我的程序中打印本地端口的行,清晰度):
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
(Java中的receive
)。但是,是否有办法告诉套接字不要监听传入的数据包?
由于
答案 0 :(得分:1)
现在,如果我运行“netstat -na”,我可以确定系统似乎在套接字的本地端口上侦听
UDP套接字具有用于传入消息的内核缓冲区。无论您是否从用户空间代码调用recv/recvfrom/recvmsg
,内核都会维护此缓冲区。
答案 1 :(得分:1)
您可以使用shutdown()
将how
参数设置为SHUT_RD
来禁用对套接字的读取,这可能具有停止侦听的预期行为,甚至可能释放内核的接收缓冲。但是接收端口必须保持为套接字的生命周期分配,因为它用作与sendto()
一起发送的传出数据包的源端口。你无法避免这种情况。
答案 2 :(得分:0)
它不仅是“侦听”该端口,而是通过该端口发送。端口分配是必需的。
,只要您调用sendto(),套接字就会绑定到端口。