识别 C++套接字端口号

发布于 2024-09-10 16:52:39 字数 152 浏览 4 评论 0原文

好的,我可以创建一个套接字并向远程计算机发送消息(顺便说一句,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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

赢得她心 2024-09-17 16:52:39

虽然可以选择特定的传出端口,但这不是通常的处理方式。

通常,客户端会选择一个随机的高编号端口(正如它所做的那样),然后服务器将检测客户端正在使用哪个端口,并回复该端口。使用 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 the recv function. The recvfrom function takes an extra two arguments which it will fill in with the address that the packet was received from, including port number.

野侃 2024-09-17 16:52:39

以下是确定本地客户端 UDP 套接字端口号的一种方法:

unsigned short local_port;   // the port number we're interested in
struct sockaddr_in sin;
int addrlen = sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = 0;  // let the system choose a port number

sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);      // create the socket
bind(sd, (struct sockaddr *)&sin, sizeof(sin));     // assign a port number
getsockname(sd, (struct sockaddr *)&sin, &addrlen); // read binding

local_port = ntohs(sin.sin_port);  // get the port number

Here's one way to determine the port number of a local, client-side UDP socket:

unsigned short local_port;   // the port number we're interested in
struct sockaddr_in sin;
int addrlen = sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = 0;  // let the system choose a port number

sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);      // create the socket
bind(sd, (struct sockaddr *)&sin, sizeof(sin));     // assign a port number
getsockname(sd, (struct sockaddr *)&sin, &addrlen); // read binding

local_port = ntohs(sin.sin_port);  // get the port number
被你宠の有点坏 2024-09-17 16:52:39

你的问题的简短答案是“bind()”,假设接口是 BSD-socket-ish。

更长的答案是

bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))

fd 是套接字的文件描述符。但是等等,你会问,这个“addr”是什么,为什么它是一个指向 struct sockaddr 的指针?

在您的情况下, addr 是

struct sockaddr_in addr;

这是一个 Internet sockaddr 结构(可以将其转换为基本 sockaddr 结构的指针)。在调用bind之前,您需要初始化addr:

addr.sin_family = AF_INET;
addr.sin_port = <your chosen port number here!>;
addr.sin_addr = INADDR_ANY;

调用bind后,套接字将绑定到您选择的端口而不是随机端口,并且您可以在该端口上发送和接收UDP消息。

The short answer to your question is "bind()", assuming an interface that is BSD-socket-ish.

The longer answer is

bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))

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

struct sockaddr_in addr;

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:

addr.sin_family = AF_INET;
addr.sin_port = <your chosen port number here!>;
addr.sin_addr = INADDR_ANY;

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.

瞄了个咪的 2024-09-17 16:52:39

假设基于 POSIX 的实现,函数 getsockname()getpeername() 可以工作,至少对于流套接字来说是这样。 recvfrom()sendto() 函数允许您获取和使用UDP 套接字的信息。

如果您使用的是 Windows,这些函数可能存在(可能带有下划线前缀),但在 MSDN 上搜索也会找到本机替代方案。

Assuming a POSIX-based implementation, the functions getsockname() and getpeername() work, at least for stream sockets. The recvfrom() and sendto() 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.

娇俏 2024-09-17 16:52:39

当您从源计算机发送消息时,会将其发送到特定的 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

只想待在家 2024-09-17 16:52:39

您应该能够在初始化套接字时设置调用的端口。我希望我能不那么含糊,但这取决于您使用的套接字实现。例如(来自 .NET 框架):

public:
void Bind(
    EndPoint^ localEP
)

与随附的 IPEndpoint 类一起使用,

public:
IPEndPoint(
    IPAddress^ address, 
    int port
)

将允许您将套接字设置为您希望的任何本地端点。您也可以选择将端口设置为零,以便自动将其分配给您。还有一个选项可以将 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):

public:
void Bind(
    EndPoint^ localEP
)

Used with the accompanying IPEndpoint class,

public:
IPEndPoint(
    IPAddress^ address, 
    int port
)

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.

桃扇骨 2024-09-17 16:52:39

考虑连接的 UDP 套接字 - 您将获得更好的性能和 ICMP 错误报告。

Consider connected UDP sockets - you'll get better performance and ICMP error reporting.

栖迟 2024-09-17 16:52:39

修复端口的一种方法是使用 bind(),这样您就可以在客户端的特定端口上发送。请注意,您应该小心不要使用标准端口。此链接将帮助您了解详细信息 http://web.mit.edu/rhel-doc/4/RH-DOCS/rhel-sg-en-4/ch-ports.html

您可以绑定 然后发送和接收您的数据包。

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = <required port number>;
addr.sin_addr = INADDR_ANY;

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.html

You can bind and then send and receive your packets.

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = <required port number>;
addr.sin_addr = INADDR_ANY;

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文