识别 C++套接字端口号
好的,我可以创建一个套接字并向远程计算机发送消息(顺便说一句,UDP)。我的问题是我需要知道我在哪个端口发送消息。远程计算机将在我发送的同一端口上做出响应。现在它似乎正在选择随机的高端口,例如 46555。有没有办法指定它出去的端口,或者有没有办法找出端口号是什么?
谢谢。
Ok, so I can create a socket and send a message to a remote machine (UDP btw). My problem is that I need to know what port I sent the message on. The remote machine is going to respond on the same port that I sent from. Right now it seems to be picking random high ports, like 46555. Is there a way to specify what port it goes out on or is there some way to find out what the port number is?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
虽然可以选择特定的传出端口,但这不是通常的处理方式。
通常,客户端会选择一个随机的高编号端口(正如它所做的那样),然后服务器将检测客户端正在使用哪个端口,并回复该端口。使用 POSIX (Berkeley) 套接字,服务器将使用
recvfrom
函数(而不是recv
函数)获取此信息。recvfrom
函数需要额外的两个参数,它将用接收数据包的地址(包括端口号)填充这些参数。While choosing a specific outgoing port can be done, it's not the way this is usually handled.
Normally, the client will choose a random, high-numbered port (as it is doing) and then the server will detect which port is being used by the client, and reply to that port. Using POSIX (Berkeley) sockets, the server would obtain this information using the
recvfrom
function, as opposed to therecv
function. Therecvfrom
function takes an extra two arguments which it will fill in with the address that the packet was received from, including port number.以下是确定本地客户端 UDP 套接字端口号的一种方法:
Here's one way to determine the port number of a local, client-side UDP socket:
你的问题的简短答案是“bind()”,假设接口是 BSD-socket-ish。
更长的答案是
fd 是套接字的文件描述符。但是等等,你会问,这个“addr”是什么,为什么它是一个指向 struct sockaddr 的指针?
在您的情况下, addr 是
这是一个 Internet sockaddr 结构(可以将其转换为基本 sockaddr 结构的指针)。在调用bind之前,您需要初始化addr:
调用bind后,套接字将绑定到您选择的端口而不是随机端口,并且您可以在该端口上发送和接收UDP消息。
The short answer to your question is "bind()", assuming an interface that is BSD-socket-ish.
The longer answer is
where fd is the file descriptor of the socket. But wait, you ask, what is this "addr", and why is it a pointer to a struct sockaddr?
In your case, addr is
Which is an Internet sockaddr structure (a pointer to which can be cast to the basic sockaddr struct). Before you call bind, you need to initialize the addr:
After calling bind, the socket will be bound to the port you have chosen rather than a random one and you can send and receive UDP messages on that port.
假设基于 POSIX 的实现,函数
getsockname()
和getpeername()
可以工作,至少对于流套接字来说是这样。recvfrom()
和sendto()
函数允许您获取和使用UDP 套接字的信息。如果您使用的是 Windows,这些函数可能存在(可能带有下划线前缀),但在 MSDN 上搜索也会找到本机替代方案。
Assuming a POSIX-based implementation, the functions
getsockname()
andgetpeername()
work, at least for stream sockets. Therecvfrom()
andsendto()
functions allow you get and use the information for UDP sockets.If you're working with Windows, these functions probably exist (probably prefixed with an underscore), but there are also native alternatives which a search on MSDN will turn up.
当您从源计算机发送消息时,会将其发送到特定的 IP 和端口。
在远程计算机上,您需要打开一个套接字,并将该套接字绑定到侦听特定端口。
无论如何,您都需要在两台机器上指定端口(使用常用的 api)。
远程计算机上的套接字正在侦听您可以定义的特定端口。
beej 的指南中有很多信息
When you send a message from the source machine, you send it to a specific IP and PORT.
On the remote machine, you need to open a socket, and bind the socket to listen on a specific port.
In any case, you do specify the port on both machines (with the usual api's).
The socket on the remote machine is listening to a specific port that you can define.
There is alot of info in beej's guide
您应该能够在初始化套接字时设置调用的端口。我希望我能不那么含糊,但这取决于您使用的套接字实现。例如(来自 .NET 框架):
与随附的 IPEndpoint 类一起使用,
将允许您将套接字设置为您希望的任何本地端点。您也可以选择将端口设置为零,以便自动将其分配给您。还有一个选项可以将 IPAddress 设置为 INADDR_ANY,不鼓励这样做。< /a>
You should be able to set the port you call out on when you initialize the socket. I wish i could be less vague, but it depends on what socket implementation you are using. For example (from the .NET framework):
Used with the accompanying IPEndpoint class,
Will allow you to set your bind your socket to any local endpoint you wish. Optionally you may set the port to zero to have it automatically assigned to you. There is also an option to have the IPAddress set to INADDR_ANY, which is discouraged.
考虑连接的 UDP 套接字 - 您将获得更好的性能和 ICMP 错误报告。
Consider connected UDP sockets - you'll get better performance and ICMP error reporting.
修复端口的一种方法是使用
bind()
,这样您就可以在客户端的特定端口上发送。请注意,您应该小心不要使用标准端口。此链接将帮助您了解详细信息 http://web.mit.edu/rhel-doc/4/RH-DOCS/rhel-sg-en-4/ch-ports.html您可以
绑定
然后发送和接收您的数据包。Beej 的指南是轻松了解套接字编程的好地方。
https://beej.us/guide/bgnet/html/single/ bgnet.html#bind
One way to fix a port would be to use
bind()
, with this you can send on a specific port on the client. Note, you should be careful not to use the standard ports. This link will help you with the details http://web.mit.edu/rhel-doc/4/RH-DOCS/rhel-sg-en-4/ch-ports.htmlYou can
bind
and then send and receive your packets.Beej's guide is a good place to get an easy understanding of socket programming.
https://beej.us/guide/bgnet/html/single/bgnet.html#bind