Crbreingan
Crbreingan

Reputation: 639

Identify C++ Socket port number

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.

Upvotes: 2

Views: 17838

Answers (8)

Tommy McGuire
Tommy McGuire

Reputation: 1253

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.

Upvotes: 2

Shrikanth N
Shrikanth N

Reputation: 652

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

Upvotes: 0

Lambtron
Lambtron

Reputation: 69

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

Upvotes: 3

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84151

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

Upvotes: 0

James
James

Reputation: 2474

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.

Upvotes: 0

Tyler McHenry
Tyler McHenry

Reputation: 76640

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.

Upvotes: 6

Itsik
Itsik

Reputation: 3930

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

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 753475

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.

Upvotes: 1

Related Questions