我有一个项目,它使用TCP套接字在服务器和一个客户端之间通信。到目前为止,我一直在一台计算机上这样做,所以我只使用了本地地址"127.0.0.1“作为两端绑定和连接的地址,它工作得很好。现在我有第二台计算机作为客户端,但我不知道如何相应地更改地址。它们是通过未连接到Internet的网络连接的。在代码看起来像这样之前-
服务器-
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
//store the connecting address and size
struct sockaddr_storage their_addr;
socklen_t their_addr_size;
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET; //local address
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
return false;
}
//make socket
fd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (fd < 0) {
printf("\nserver socket failure %m", errno);
return false;
}
//allow reuse of port
int yes=1;
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*) &yes,sizeof(int)) == -1) {
perror("setsockopt");
return false;
}
//unlink and bind
unlink("127.0.0.1");
if(bind (fd, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nBind error %m", errno);
return false;
}
客户端-
struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results
memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET; //local address
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address
//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
return false;
}
//make socket
fd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (fd < 0) {
printf("\nserver socket failure %m", errno);
return false;
}
//connect
if(connect(fd, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
printf("\nclient connection failure %m", errno);
return false;
}
我知道这应该很简单,但我想不出如何更改it来让它们工作。我尝试在这些行的引号中设置服务器计算机的IP地址- if ((status = getaddrinfo("127.0.0.1",port,&hints,&servinfo)) != 0)和unlink("127.0.0.1");
然后将客户端代码中的地址更改为此行中客户端计算机的IP地址- if ((status = getaddrinfo("127.0.0.1",port,&hints,&servinfo)) != 0)
每当我这样做时,它都会告诉我连接被拒绝。我还尝试了相反的方法,将服务器地址放在客户机行中,将客户机地址放在服务器行中,并进行了一些其他尝试。在这一点上,我觉得我只是在猜测。那么,有没有人能帮我理解一下,如何将这一点从一台计算机使用本地地址改为连接两台计算机?任何帮助都是非常感谢的。
发布于 2011-08-11 05:07:21
首先,unlink("127.0.0.1");
在这里是完全错误的,不要那样做。
然后,你有两台计算机通过某个网络连接起来。两者都应该有IP地址。在客户端和服务器端,用服务器的IP地址替换127.0.0.1
。服务器不必事先知道客户端的地址-它会从accept(2)
调用中获取该信息。客户端需要服务器的地址才能知道连接到哪里。服务器需要自己的地址才能进行bind(2)
调用。
发布于 2011-08-11 05:08:20
主要的问题是你把AI_PASSIVE放在你的客户端代码中。AI_PASSIVE仅适用于服务器(这就是它发出的信号)。
同样在服务器端,你首先不应该调用unlink。这只适用于AF_UNIX套接字,而不适用于AF_INET。其次,您不需要在服务器端的getaddrinfo行中放入"127.0.0.1“。最好使用NULL绑定到所有可用的地址。
如果你改变了这些东西,我相信你的代码应该可以工作。然而,实际上您应该使用ai_next指针循环访问getaddrinfo结果,并尝试使用第一个成功的结果连接到每个结果。
发布于 2011-08-11 05:11:26
Connection Refused
通常意味着您的客户端收到了指向其SYN
的RST
。这通常是由于您尝试连接的端口上的服务器上缺少侦听套接字造成的。
netstat -ant
。是否在端口上看到处于LISTEN
状态的条目?类似于:
tcp4 0 0 *.3689 *.* LISTEN
我敢打赌您没有,因此您的服务器侦听套接字有问题。我还打赌您对这行所做的更改:
if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {
都不是很正确。尝试在服务器上将该IP更改为0.0.0.0
,以告知其绑定到系统上的任何IP。在客户端上,该行应该包含服务器的IP地址。您还应该删除服务器中的unlink()
调用;不必要。
如果你有一个监听套接字,那么在你的机器之间可能有一个防火墙或什么东西阻止了SYN。尝试在两个系统的命令行界面上键入service iptables stop
。
https://stackoverflow.com/questions/7017730
复制相似问题