[英]Narrowing Conversion from int to char inside { } | An issue with signedness of char
[英]Structure issue and int to char* conversion
在我的第一个程序中,我找到一个本地IP地址(int iip),我想发送的是该IP地址以及结构(Ins c)中的端口(int port = 1100)。 然后,我希望第二个程序接收此结构,并选择IP地址和端口,以便以后在TCP连接中使用。
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");
在一个程序中,我收到以下结构:
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;
在头文件MonReqServer.hh中,我将tcp_ip和tcp_port声明为char *,因为这是设置tcp套接字所需要的。
private:
char* tcp_ip;
char* tcp_port;
以下是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;
};
}
这些是我的错误:
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'
那么我的问题是,一旦收到地址,我该如何将其转换为char *? 具体来说,从int切换为char *的命令是什么,我该怎么暗含它? 还为什么说Ins没有名为port的成员? 我以为Ins应该使用一个IP地址和一个端口? 如果我的问题不清楚或需要其他信息,请告诉我。 谢谢!
首先,危险危险!
char* tcp_ip;
char* tcp_port;
这些指针需要指向某个事物,并且它必须具有某种持久性。 我认为这种情况不太可能发生,因此您应该在此处定义存储。
char tcp_ip[SizeOfBiggestIPAddressPossible];
char tcp_port[SizeOfBiggestPortNumberPossible];
哪里
#define SizeOfBiggestIPAddressPossible (4+1+4+1+4+1+4+1+4+1+4+1+4+1+4+1)
#define SizeOfBiggestPortNumberPossible (5+1)
但是,这只是愚蠢的。 由于OP标记为C ++,所以我们只使用几个字符串即可,从而避免了缓冲区溢出和其他怪异的麻烦。
std::string tcp_ip;
std::string tcp_port;
接下来,将数字更改为字符串在这里毫无价值。 字符串编号适用于端口号...
tcp_port = std::to_string(c.portId());
或者如果缺少C ++ 11支持,请创建以下函数
template <class TYPE>
std::string toString(TYPE val)
{
std::stringstream temp;
temp << val;
return temp.str();
}
叫它
tcp_port = toString(c.portId());
但是将数字转换为IP地址完全是另一回事。 IP地址是带点或冒号与数字混合的格式化字符串。 如果有一个很好的C ++方法可以做到这一点,我不知道。
在* nux land中,您调用inet_ntop 。
假设Ipv4(未经编译和测试,但应接近):
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
}
在Windows中,您可以调用相同的函数,也可以调用整个Windows专用替代方案。
现在,您有两个不错的,礼貌的C ++字符串,可以为您完成所有的内存管理工作。 要获取C样式字符串(const char *),请使用c_str
方法。
const char * addrp = c.address().c_str();
如果您需要一个非const char *,那么值得一巴掌。
这将使您获得字符串形式的地址,但不支持将来。 或者说IPv6过去已有35年了?
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();
首先,您的成员称为_port和_address,而不是端口和地址。 它们不是公共的,因此可以使用函数portId()和address()获得它们。其次,要将数字转换为c字符串,可以使用sprintf或itoa函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.