Reputation: 41
In my first program I find a local ip address (int iip) and what I would like to do is send that ip address as well as the port (int port = 1100) in a structure (Ins c). Then I would like the second program to receive this structure and pick out the ip address and port to use in a tcp connection later on.
n_addr inaddr;
inaddr.s_addr = htonl(iip);
int udp_socket_info;
struct sockaddr_in udp_server;
udp_socket_info = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_socket_info == -1) {
puts("Could not create udp socket");
}
puts("Udp socket created");
udp_server.sin_addr.s_addr = inet_addr("225.0.0.37");
udp_server.sin_port = htons(1100);
udp_server.sin_family = AF_INET;
int port = 1100;
Ins c(iip, port);
sendto(udp_socket_info, &c, sizeof(c), 0, (struct sockaddr *)&udp_server, sizeof(udp_server));
puts("STRUCT Message Sent");
In one program I am receiving the following structure:
Ins c;
if (recvfrom(udp_socket_info, &c, sizeof(c), 0, &addr, &fromlen) < 0) {
perror("Recvfrom error:");
}
puts("STRUCT Message Received");
tcp_ip = c.address;
tcp_port = c.port;
In the header file MonReqServer.hh I declare tcp_ip and tcp_port as char* because that is what I need to use to setup the tcp socket.
private:
char* tcp_ip;
char* tcp_port;
And the following is the header for Ins.hh
namespace Pds {
class Ins
{
public:
Ins();
enum Option {DoNotInitialize};
explicit Ins(Option);
explicit Ins(unsigned short port);
explicit Ins(int address);
Ins(int address, unsigned short port);
Ins(const Ins& ins, unsigned short port);
explicit Ins(const sockaddr_in& sa);
int address() const;
void address(int address);
unsigned short portId() const;
int operator==(const Ins& that) const;
protected:
int _address;
unsigned _port;
};
}
These are my errors:
MonReqServer.cc: In member function 'virtual void Pds::MonReqServer::routine()':
MonReqServer.cc:79: error: cannot resolve overloaded function 'address' based on conversion to type 'char*'
MonReqServer.cc:80: error: 'class Pds::Ins' has no member named 'port'
My question then is how do I convert my address into a char* once I receive it? Specifically what is the command to switch from int to char* and how do I impliment it? Also why does it say Ins has no member named port? I thought an ip address and a port are what Ins is meant to take? Please let me know if my questions are unclear or if you need any other information? Thank you!
Upvotes: 0
Views: 295
Reputation: 33952
First off, danger danger!
char* tcp_ip;
char* tcp_port;
These pointers need to point to something, and it has to be something with a measure of permanence. I don't see this as likely to happen, so you should define the storage here.
char tcp_ip[SizeOfBiggestIPAddressPossible];
char tcp_port[SizeOfBiggestPortNumberPossible];
where
#define SizeOfBiggestIPAddressPossible (4+1+4+1+4+1+4+1+4+1+4+1+4+1+4+1)
#define SizeOfBiggestPortNumberPossible (5+1)
But this is just stupid. Since OP tagged for C++, let's just use a couple strings and save us the trouble of buffer overflows and other weirds.
std::string tcp_ip;
std::string tcp_port;
Next, changing a number into a string is half worthless here. Number to string works for the port number...
tcp_port = std::to_string(c.portId());
Or if lacking C++11 support create the following function
template <class TYPE>
std::string toString(TYPE val)
{
std::stringstream temp;
temp << val;
return temp.str();
}
and call it
tcp_port = toString(c.portId());
but to convert a number to an IP address is another beast entirely. the IP address is a formatted string with dots or colons intermixed with numbers. If there is a good C++ way to do this, I don't know it.
In *nux land, you call inet_ntop.
Assuming Ipv4 (not compiled and tested, but should be close):
char temp[INET_ADDRSTRLEN];
struct sockaddr_in sockAddr;
sockAddr.sin_addr.S_un.S_addr = htonl(c.address());
if (inet_ntop(AF_INET, &addr, temp, INET_ADDRSTRLEN)!= null)
{
tcp_ip = temp;
}
else
{
std::cerr << "Bad address" << std::endl;
// handle error
}
In Windows you can call the same function or a whole raft of Windows-specific alternatives.
You now have two nice, polite C++ strings doing all of the memory management heavy lifting for you. To get C style strings (const char *) back use the c_str
method.
const char * addrp = c.address().c_str();
If you need a non const char * someone deserves a slap.
This will get you the address as a string, but it doesn't support the future. Or the past as IPv6 has been around for what, 35 years?
uint32_t temp = c.address();
std::stringstream addr;
addr << ((temp >> 24) & 0xFF) << '.' <<
((temp >> 16) & 0xFF) << '.' <<
((temp >> 8) & 0xFF) << '.' <<
((temp >> 0) & 0xFF);
tcp_ip = addr.str();
Upvotes: 1
Reputation: 905
First of all your members are called _port and _address and not port and address. They are not public, so you can obtain them with your functions portId() and address() Second, to convert number to c string, you can use sprintf or itoa functions.
Upvotes: 0