SFML community forums
Help => Network => Topic started by: ldrrn on August 19, 2007, 07:53:33 pm
-
i wish the source port number will be exposed to application layer, from what i learn, current sfml implementation, only the source ip is returning back to application layer.
my convention: source == sender, dest == receiver :), what i'm trying to do is to get sender port number at the receiver end.
-
i did a quick hack to fulfil my own needs, i post it here hopefully some one could benefit from it, and even get it merge into official code base.
modified these two lines in Network/ipaddress.hpp
IPAddress(const std::string& Address, Uint16 port = 0);
IPAddress(Uint8 Byte0, Uint8 Byte1, Uint8 Byte2, Uint8 Byte3, Uint16 port = 0);
and add these lines into Network/ipaddress.hpp
Uint16 getPort() const { return myPort; }
void setPort(Uint16 port) { myPort = port; }
...
private:
Uint16 myPort;
modified these lines in Network/ipaddress.cpp
IPAddress::IPAddress(const std::string& Address, Uint16 port) :
myPort(port)
{
...
}
IPAddress::IPAddress(Uint8 Byte0, Uint8 Byte1, Uint8 Byte2, Uint8 Byte3, Uint16 port) :
myPort(port)
{
...
}
add this line into Network/SocketUDP.cpp in method SocketUDP::Receive()
Address.setPort(htons(Sender.sin_port));
actually many things need to modified with this new changes, for example
bool SocketTCP::Connect(unsigned short Port, const IPAddress& HostAddress)
can be simplified to
bool SocketTCP::Connect(const IPAddress& HostAddress)
but since this is a quick hack, i leave it to you.
-
I don't get it. A UDP socket will always receive data on the port it's bound to, so the port is always known. What am I missing ?
-
the port number i needed to know isn't the port it bound to, but the port of the remote pc, the sender used port number. for my application, the receiver and sender are using different port number, different from the example you wrote.
-
Are you telling me the sender is not sending data to the same port the receiver gets it ?
-
Exactly, that's the situation i'm facing, that's why i'd to make this ugly hack
-
I modified the sockets sample so that the client and the server don't use the same port, and as a result the server never receives anything. I really don't see how two sockets could communicate on two different ports.
I can't find a good reference for this behavior, so if you know a good document describing it I would be very interested to see it :)
PS : you don't need to do so many changes in the code, just pass the last parameter of sfSocketUDP::Receive (the port) by reference so that the function can overwrite it and pass it back to the caller.
-
is hard to find an exact document to explain it, i'll try to explain it myself. if you look at the udp header diagram http://www.erg.abdn.ac.uk/users/gorry/course/inet-pages/udp.html
you could see there are two fields in the header, one for source port and one for destination port, so having source and destination port with different number is not an issue.
regarding the problem you can't get your example to work with different port numbers, i guess this is what you did
if (Who == 's')
{
// Run as a server
if (Protocol == 't')
DoServerTCP(PortA); // was Port
else
DoServerUDP(PortA); // was Port
}
else
{
// Run as a client
if (Protocol == 't')
DoClientTCP(PortB); // was Port
else
DoClientUDP(PortB); // was Port
}
doing these won't help you to set source and destination ports to different number, because the PortA is used to set the server's source port number and PortB is used to set the client's destination port number, therfore they have to be the same.
to make it works you need to send two port numbers to DoClientUDP(), for example
DoClientUDP(PortB, PortA);
...
void SocketUDP::Create()
{
...
mySocket = socket(AF_INET, SOCK_DGRAM, 0);
ret= bind(mySocket , PortB);
...
}
...
bool SocketUDP::Send(const char* Data, std::size_t Size, const IPAddress& Address, unsigned short PortA)
{
...
Target.sin_family = AF_INET;
Target.sin_port = htons(PortA);
Target.sin_addr.s_addr = inet_addr(Address.ToString().c_str());
...
}
i believe this will work, but i didn't try this, because i used my existing client and only use sfml to program a new server.
PS : you don't need to do so many changes in the code, just pass the last parameter of sfSocketUDP::Receive (the port) by reference so that the function can overwrite it and pass it back to the caller.
i try not to do this, because it might break the existing code, if someone reuse the "port" without knowing it has been "corrupted"
-
Ok, I see. I didn't know about this, thank you very much for the explanations.
-
i'm glad that i could contribute to the open source community.