在 C 中编译套接字连接代码时出现问题

发布于 2024-11-10 05:47:41 字数 647 浏览 0 评论 0原文

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));

尝试编译时,出现以下错误:

错误:无法将参数 '2' 的 'sockaddr_in*' 转换为 'const sockaddr*' 到 'int connect(int, const sockaddr*, socklen_t)'

事情看起来“按书本”,但我遗漏了一些东西(显然)。它是什么?

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));

When trying to compile, I get the following error:

error: cannot convert ‘sockaddr_in*’ to ‘const sockaddr*’ for argument ‘2’ to ‘int connect(int, const sockaddr*, socklen_t)’

Things look "by the book", but I am missing something (obviously). What is it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

帥小哥 2024-11-17 05:47:41

我认为您在 sockaddr_in socketInfo 上缺少 struct 。所以它应该是struct sockaddr_in socketInfo

另外,将 socketInfo 转换为 struct sockaddr * 也不错。

connect(socketDescriptor,&socketInfo,sizeof(socketInfo));

应该是

connect(socketDescriptor,(struct sockaddr *) &socketInfo,sizeof(socketInfo));

I think you are missing struct on sockaddr_in socketInfo. So it should be struct sockaddr_in socketInfo.

Also casting socketInfo to struct sockaddr * would be nice.

connect(socketDescriptor,&socketInfo,sizeof(socketInfo));

Should be

connect(socketDescriptor,(struct sockaddr *) &socketInfo,sizeof(socketInfo));
傾城如夢未必闌珊 2024-11-17 05:47:41
  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)

这些是一些可行的代码,您可以从它们开始。

这里发生的事情是,我设置了一个包含所有英特尔的结构,然后将其与更多信息结合起来,以获得一个很好的所有指针都适合的结构,也可以通过连接。
希望有帮助

  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)

Those are some codesnipets that will work and that you can start from.

What happens here is that I set up one struct with all the intel and than combine it with some more info to get one nice all pointers fit structure too pass to connect.
hope that helps

扛刀软妹 2024-11-17 05:47:41

套接字接口除了非常旧之外,还被故意以这种方式破坏。 sockaddr_* 结构隐式地以 sockaddr 的相同成员开始,因此可以安全地将它们转换为“基本”类型。 struct sockaddr 也有一个 sa_family 成员,因此您还可以在运行时决定给定 struct sockaddr* 的“派生”(尽管不是真正的)类型将其投射到。

因此,要改变这一点,您可以做的最小的事情是将 struct sockaddr_in* 转换为 struct sockaddr* 。通常这会是非常无礼的。但别担心;在这种情况下,每个人都在这样做。我什至可能更喜欢转换为 void* 因为它的字符较少,并且您将获得到 struct sockaddr* 的隐式转换。

但是...其他一些不相关的点:

  1. gethostbyname 可能会失败。事实上,这种情况经常发生,比如当用户输入虚假地址时。当这种情况发生时,你的程序将会崩溃。检查它是否返回 NULL 以避免这种情况。

  2. 实际上,gethostbyname 已被 getaddrinfo 取代。用那个。它将使您独立于协议,这样您就不会受到 IPv4 的束缚。它还会返回一个struct sockaddr*,这样您就不必进行丑陋的转换。

The socket interfaces, in addition to being very old, are deliberately broken in this way. The sockaddr_* structs implicitly start with the same members of sockaddr so it's safe to cast them to the "base" type. struct sockaddr also has an sa_family member so you can also decide at runtime given a struct sockaddr* which "derived" (though not really) type to cast it to.

So, the smallest thing you can do to change this is cast the struct sockaddr_in* to struct sockaddr*. Normally this would be very offensive. But don't worry; in this instance everyone is doing it. I might even prefer to cast to void* because it's fewer characters and you'll get the implict conversion to struct sockaddr*.

However... A few other unrelated points:

  1. gethostbyname can fail. In fact it happens pretty often, say when the user types in a bogus address. Your program will crash when that happens. Check to see if it returned NULL to avoid this.

  2. Actually, gethostbyname has been superseded by getaddrinfo. Use that. It will get you protocol-independence so that you're not tied to IPv4. It also returns you a struct sockaddr* so you don't have to do the ugly cast.

她如夕阳 2024-11-17 05:47:41

如果只是 const 就可以了,但显然 sockaddr 和 sockaddr_in 是不同的类型。

If it was just the const it would work, but obviously sockaddr and sockaddr_in are different types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文