套接字编程 connect() 函数错误——“无法将 'main(int, char**)::sockaddr* 转换为 'const sockaddr”

Posted

技术标签:

【中文标题】套接字编程 connect() 函数错误——“无法将 \'main(int, char**)::sockaddr* 转换为 \'const sockaddr”【英文标题】:Socket programming connect() function error -- "cannot convert 'main(int, char**)::sockaddr* to 'const sockaddr"套接字编程 connect() 函数错误——“无法将 'main(int, char**)::sockaddr* 转换为 'const sockaddr” 【发布时间】:2020-12-03 09:04:49 【问题描述】:

一段时间以来,我一直在尝试将作为套接字编程函数从 Winsock 重写为等效的 Unix 版本。尝试编译代码时,我无可救药地陷入了 connect() 函数的错误:"cannot convert 'main(int, char*)::sockaddr* to 'const sockaddr"* 我想这是一个铸造错误,但我完全无法修复它。为了模拟现有代码,我重新创建了 Winsock 使用的一些结构。我真的很绝望,因为目的是为我的高级设计项目与设备进行通信。任何帮助将不胜感激。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>  
#include <netinet/in.h>
#include <netdb.h>

int main(int argc, char **argv)

    struct SOCKADDR_IN 
        short sin_family;
        u_short sin_port;
        struct in_addr sin_addr;
        unsigned char sin_zero[8];  
    addrSrv;
    
    struct in_addr 
        union 
            struct  u_char s_b1,s_b2,s_b3,s_b4;  S_un_b;
            struct  u_short s_w1, s_w2;  S_un_w; 
            unsigned long S_addr;
        S_un;
    ;

    struct sockaddr 
        u_short sa_family;
        char sa_data[14];
    ;
    //typedef struct sockaddr SOCKADDR;
    
    int sockClient;
    sockClient = socket(AF_INET, SOCK_STREAM, 0);
       
    inet_pton(AF_INET, SERVER_IP, (char*)&addrSrv.sin_addr.s_addr);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(IP_PORT);
            
    
    connect(sockClient, (struct sockaddr *) &addrSrv, sizeof(addrSrv));

【问题讨论】:

我将开始删除所有 SOCKADDR_IN、in_addr 和 sockaddr 的重新定义,添加正确的包含语句。见docs.microsoft.com/en-us/windows/win32/api/ws2def/… 或man7.org/linux/man-pages/man7/ip.7.html 感谢您的回复。我查看了头文件 socket.h 并且没有 SOCKADDR_IN 的结构定义。我认为赢得头文件可能是一个错误,但我从 linux 手册页中看到它不是头文件的一部分。我开始定义结构以解决编译器看不到的 inet_pton 和 addrsrv 错误。但也许是因为我从原始 winsock 使用中转移的名称,这些名称没有在 inet.h 头文件中定义。 嗨,Brian,通常 win 和用于套接字处理的 Linux 结构非常接近,大多数情况下它们只有不同的名称。我使用了一些#define,我记得 SOCKET_STORAGE(用于 Win 上的 ipv4 和 ipv6 地址),在 Linux 上我使用 #define SOCKET_STORAGE sockaddr_storage,使 win 代码在 Linux 上也可以正常运行。希望它可以帮助,Ste 【参考方案1】:

struct sockaddr *

connect(sockClient, (struct sockaddr *) &addrSrv, sizeof(addrSrv));

指的是你在main()中定义的结构体

  struct sockaddr 
        u_short sa_family;
        char sa_data[14];
  ;

但是,connect() 期望接收的是const sockaddr *,其中sockaddr&lt;sys/socket.h&gt; 中定义

/* Structure describing a generic socket address.  */
struct sockaddr

    __SOCKADDR_COMMON (sa_);    /* Common data: address family and length.  */
    char sa_data[14];       /* Address data.  */
;

编译器无法将您定义的struct sockaddr * 隐式转换为&lt;sys/socket.h&gt; 定义的const sockaddr *

您可以删除您在main() 中定义的所有结构定义,它们应该已经在各种 Unix 库头文件中定义。

【讨论】:

感谢您的回复!我认为我需要写出结构定义很奇怪,但是如果没有定义它们,我会得到“变量(如 addrsrv)未在范围内声明”错误。为了简洁起见,我拒绝在我发布的代码中声明我的头文件,但它们如下...... 在上面的代码中。我不确定 是否等同于 。也许我错误地编译了 sock 库,但是如果我搜索: find /usr/include -name socket.h >> /usr/include -name socket.h /usr/include/asm-generic/socket.h /usr/include /arm-linux-gnueabihf/bits/socket.h /usr/include/arm-linux-gnueabihf/sys/socket.h /usr/include/arm-linux-gnueabihf/asm/socket.h /usr/include/linux /socket.h 它是 。对你来说,它应该是/usr/include/arm-linux-gnueabihf/sys/socket.h,你可以通读这个文件,你应该找到sockaddr的定义。你应该检查为什么你的编译器没有找到这个文件(或者为什么它找到了另一个 socket.h 而不是这个)。 我写的是socket.h,但是别人改成,真的应该是,我会相应修改答案。

以上是关于套接字编程 connect() 函数错误——“无法将 'main(int, char**)::sockaddr* 转换为 'const sockaddr”的主要内容,如果未能解决你的问题,请参考以下文章

connect函数

linux网络编程,可以用select函数代替accept函数接收客户端的connect请求吗

《Python》网络编程之验证客户端链接的合法性socketserver模块

UNIX网络编程卷1 时间获取程序client TCP 使用非堵塞connect

C语言socket connect()函数(未完)

socket编程 ------ 客户端(非阻塞方式)