struct hostent *lh = gethostbyname(hostname);
int socketDescriptor = socket(AF_INET,SOCK_STREAM, 0);
sockaddr_in socketInfo;
memset(&socketInfo, 0, sizeof(socketInfo));
socketInfo.sin_family = AF_INET;
socketInfo.sin_addr.s_addr = ((in_addr *)(lh->h_addr))->s_addr;
socketInfo.sin_port = htons(portNumber);
connect(socketDescriptor,&socketInfo,sizeof(socketInfo));
尝试编译时,出现以下错误:
error: cannot convert ‘sockaddr_in*’ to ‘const sockaddr*’ for argument ‘2’ to ‘int connect(int, const sockaddr*, socklen_t)’
事情看起来“按书”,但我遗漏了一些东西(显然)。它是什么?
答案 0 :(得分:12)
我认为你struct
上遗失了sockaddr_in socketInfo
。所以它应该是struct sockaddr_in socketInfo
。
同时将socketInfo
投射到struct sockaddr *
也不错。
connect(socketDescriptor,&socketInfo,sizeof(socketInfo));
应该是
connect(socketDescriptor,(struct sockaddr *) &socketInfo,sizeof(socketInfo));
答案 1 :(得分:3)
struct addrinfo *server;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));/*set hints*/
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0; /* Any protocol */
getaddrinfo(srvname,port,&hints,&server); /*get server ip fit args*/
sid = socket(server->ai_family, server->ai_socktype,server->ai_protocol)
connect(sid,server->ai_addr, server->ai_addrlen)
这些是一些可行的代码管理,您可以从中开始。
这里发生的是我设置了一个包含所有英特尔的结构,而不是将它与一些更多的信息结合起来,以获得一个不错的所有指针适合结构也传递给连接。 希望有所帮助
答案 2 :(得分:1)
如果它只是const
它会起作用,但显然sockaddr
和sockaddr_in
是不同的类型。
答案 3 :(得分:1)
套接口除了非常陈旧外,还会以这种方式故意破坏。 sockaddr_*
结构隐式地以sockaddr
的相同成员开头,因此将它们转换为“基础”类型是安全的。 struct sockaddr
也有一个sa_family
成员,所以你也可以在运行时决定给出一个struct sockaddr*
哪个“派生”(虽然不是真的)类型来投射它。
因此,您可以做的最小的改变就是将struct sockaddr_in*
强制转换为struct sockaddr*
。通常这会非常令人反感。但别担心;在这种情况下,每个人都在这样做。我甚至可能倾向于转换为void*
,因为它的字符数较少,您可以将隐含转换为struct sockaddr*
。
然而......其他一些不相关的观点:
gethostbyname
可能会失败。实际上它经常发生,例如当用户键入虚假地址时。发生这种情况时,你的程序会崩溃。检查它是否返回NULL
以避免这种情况。
实际上,gethostbyname
已被getaddrinfo
取代。用那个。它将使您获得协议独立性,这样您就不会受到IPv4的束缚。它还会返回struct sockaddr*
,因此您不必进行丑陋的演员表。