我试图创建一个客户端-服务器井字游戏作为家庭作业。我正在设置服务器-监听器和连接在不同的函数中,而不是在主程序中。服务器套接字创建成功,但客户端连接失败,我认为这是导致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
如果你能向我解释我做错了什么,那将是非常有帮助的。
您注意到收到的警告是正确的:
警告:将'int'传递给'socklen_t*'(又称'unsigned int*')[-Wint conversion]clientsocket[con_num]=accept(serversocket,(struct sockaddr)类型的参数的整数到指针转换不兼容
你打折扣是错误的:
然而,我检查的所有示例都是这样通过的。
如果你看过的所有例子都使用与你类似的代码,那么你迫切需要找到更好的例子。然而,更重要的是,你需要学会依赖留档,最好是作为你的第一个求助对象,但至少要清除不确定性,比如“这个警告是我应该关心的吗?”(提示:除非你能表达一个基于留档的原因,否则答案总是“是的,我应该关心警告”。)
快速浏览接受()
的文档会发现,第三个参数应该是一个指针,指向一个包含您传递的地址对象大小的变量,函数将更新该变量(通过指针),以包含返回的地址的实际长度。相反,您正在传递大小本身,转换为指针几乎肯定会产生无效的大小。实际上,您很幸运它会这样做,这样您就会得到一个运行时错误,因为另一种选择是您在程序中的某个随机位置默默地产生内存损坏。
请注意,bind()
是不同的。它要求您直接传递地址的大小,而不是间接传递。这是合理的,因为它没有理由想要修改大小。
我在编译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 检查它是否正在使用并获得结果 在手动创建文件 授予用户权限 试图删除并重新安装,但仍然无法正常工作