当前位置: 首页 > 知识库问答 >
问题:

TCP-IP套接字C:尝试连接到服务器套接字时错误的地址

陆英毅
2023-03-14

我试图创建一个客户端-服务器井字游戏作为家庭作业。我正在设置服务器-监听器和连接在不同的函数中,而不是在主程序中。服务器套接字创建成功,但客户端连接失败,我认为这是导致seg故障的原因。

我已经查找了类似的问题,并尽可能地对代码进行了调整,比如为sizeof(cli_addr)设置一个变量,而不是直接将其传递给accept()。我不知道为什么它不起作用。

这是设置连接的函数

void setup_connections(int serversocket,int *clientsocket,int portnum){
int cli_size,con_num = 0;
struct sockaddr_in cli_addr;

//server is listening for clients
listen(serversocket,5);

while(con_num<2){


    cli_addr.sin_family = AF_INET;
    cli_addr.sin_addr.s_addr = INADDR_ANY;
    cli_addr.sin_port = htons(portnum);

    //accept connection while creating client socket
    cli_size = sizeof(cli_addr);
    clientsocket[con_num] = accept(serversocket,(struct sockaddr *) &cli_addr,cli_size);

    if(clientsocket[con_num]<0){
        perror("Error: ");
    }

    con_num++;

    }
}

我在编译cli_大小类型时收到警告。

*警告:将'int'传递给'socklen_t*'(又称'unsigned int*')[-Wint conversion]clientsocket[con_num]=accept(serversocket,(struct sockaddr)类型的参数的整数到指针转换不兼容

然而,我检查的所有示例都是这样通过的。

这是设置服务器套接字的函数。

int setup_server(int portnum){
int serversocket,serv_bind;
struct sockaddr_in server_addr;


serversocket = socket(AF_INET, SOCK_STREAM, 0);
if(serversocket<0){
    printf("Failed to create server\n");
}

//set up server info
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(portnum); //port number given by user

//link server address to socket
serv_bind = bind(serversocket,(struct sockaddr *) &server_addr,sizeof(server_addr));
if(serv_bind<0){
    printf("Failed to bind\n");
}

return serversocket;
}

这是主要的代码。这就叫它们:

int portnum,serversocket, clientsocket[2]; //sockets


portnum = atoi(argv[1]);
if(argc < 2){
    printf("Port number not given");
}

//create sockets
serversocket = setup_server(portnum);
setup_connections(serversocket,clientsocket);

运行该程序后,我得到的是:

错误::地址不正确

错误::地址不正确

分段错误:11

如果你能向我解释我做错了什么,那将是非常有帮助的。

共有2个答案

戎桐
2023-03-14

您注意到收到的警告是正确的:

警告:将'int'传递给'socklen_t*'(又称'unsigned int*')[-Wint conversion]clientsocket[con_num]=accept(serversocket,(struct sockaddr)类型的参数的整数到指针转换不兼容

你打折扣是错误的:

然而,我检查的所有示例都是这样通过的。

如果你看过的所有例子都使用与你类似的代码,那么你迫切需要找到更好的例子。然而,更重要的是,你需要学会依赖留档,最好是作为你的第一个求助对象,但至少要清除不确定性,比如“这个警告是我应该关心的吗?”(提示:除非你能表达一个基于留档的原因,否则答案总是“是的,我应该关心警告”。)

快速浏览接受()的文档会发现,第三个参数应该是一个指针,指向一个包含您传递的地址对象大小的变量,函数将更新该变量(通过指针),以包含返回的地址的实际长度。相反,您正在传递大小本身,转换为指针几乎肯定会产生无效的大小。实际上,您很幸运它会这样做,这样您就会得到一个运行时错误,因为另一种选择是您在程序中的某个随机位置默默地产生内存损坏。

请注意,bind()是不同的。它要求您直接传递地址的大小,而不是间接传递。这是合理的,因为它没有理由想要修改大小。

景宏盛
2023-03-14

我在编译cli_大小类型时收到警告。

*警告:将'int'传递给'socklen_t*'(又称'unsigned int*')[-Wint conversion]clientsocket[con_num]=accept(serversocket,(struct sockaddr)类型的参数的整数到指针转换不兼容

然而,我检查的所有示例都是这样通过的

不,他们不会。如果他们这样做了,他们会在编译时得到与您相同的错误。

这是accept

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//                                                      ^ Note the asterisk

您可以清楚地看到,它需要指向socklen_t的指针,而不是socklen_t。您的accept行应该如下所示:

clientsocket[con_num] = accept(serversocket,(struct sockaddr *) &cli_addr,&cli_size); 
//                                                                        ^ Note the pointer indirection

如果要使用cli_addr结构,则应检查返回的大小是否大于传入的大小,因为如果大于,则表示地址结构已被截断。

Linux页面是这么说的

addrlen参数是一个值结果参数:调用者必须初始化它,以包含addr指向的结构的大小(字节);返回时,它将包含对等地址的实际大小。

 类似资料:
  • 真的需要你帮忙。 我的项目是通过电缆连接两台PC机,并使用tcp套接字将客户端文本框形式的字符串发送到服务器。问题是ATI只能发送一个字符串,然后连接就会关闭。 注意:某个端口上的连接将在表单加载中建立并成功。

  • 线程“main”java.net.ConnectException:连接超时:在java.net.dualStackplainsockeTimpl.Connect0(本机方法)在java.net.dualStackplainsockeTimpl.socketConnect(DualStackplainsockeTimpl.java:69)在java.net.abstractplainsockeTi

  • 我有两个真实的IP地址220.xx.xxx.xxx在我的工作场所。我试着做了一个简单的java tcp服务器程序和android tcp客户端程序。Android客户端正常工作时: 服务器和仿真器程序在同一台pc上。 一台具有真实IP地址的电脑中的服务器位于另一台具有真实IP地址的电脑中 服务器和仿真器都位于同一台pc或不同pc或设备的专用网络下 在以下情况下不工作: 客户端是一个具有wifi或3

  • 首先我要感谢你花时间... 我在macbook中用C++创建了一个服务器套接字,在运行windows XP的不同机器中用Java创建了一个客户机/套接字。我已将端口指定为5000,但无法指定正确的主机,因此无法进行连接。当我在windows xp中使用WinSock2创建一个C++服务器/套接字时,当我使用本地主机时,连接是完美的...有什么想法吗??? 提前Thnx int main(int a

  • 在套接字最终接受另一端消失的情况下,什么指定了这个超时?是操作系统(Ubuntu 11.04),还是来自TCP/IP规范,还是套接字配置选项?

  • 问题内容: 错误2002(HY000):无法通过套接字’/var/run/mysqld/mysqld.sock’(2)连接到本地MySQL服务器 我尝试了在互联网上找到的所有内容,但是无法解决在Ubuntu 11.04上出现的问题。 我尝试了这些事情: 使用手动启动mysqld 使用启动mysqld 检查它是否正在使用并获得结果 在手动创建文件 授予用户权限 试图删除并重新安装,但仍然无法正常工作