tags:

views:

137

answers:

6

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.

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.

James
+1  A: 

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

Itsik
A: 

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.

Jonathan Leffler
+3  A: 

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.

Tyler McHenry
Exactly right. You don't actually need to know what port you used - you just `recv()` on the same socket that you `send()`, and it'll listen on the same port that it sent from.
caf
+2  A: 

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

Tommy McGuire
So if I understand you correctly, bind makes the socket "attach" to a local address(network interface) and port. And then I call sendto() and recvfrom() in order to send or receive from a specific device/IP address? Is this correct?
Crbreingan
Right. Bind associates a local port and address with the socket (to use a specific network address, replace INADDR_ANY), replacing the random port that is used when the socket is created. The inverse is connect(), which associates a remote port and address (and a good bit more work for TCP). Normally, you don't use connect with UDP, though, but instead use sendto() and recvfrom().Typically, a "server" would use bind() and a "client" would use the random port, as described by Tyler McHenry. And, do check out beej's guide mentioned by Itsik.
Tommy McGuire
A: 

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

Nikolai N Fetissov