2

我有一个项目使用 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;
}

我知道这应该很简单,但我不知道如何更改 IP 以使其正常工作。我尝试在这些行的引号中设置服务器计算机的 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)

每当我这样做时,它都会告诉我连接被拒绝。我也尝试过相反的方式,将服务器的地址放在客户端的行中,将客户端的地址放在服务器的行中,以及其他一些尝试。在这一点上,我觉得我只是在猜测。那么有人可以帮助我了解如何将其从使用一台计算机的本地地址更改为连接两台计算机吗?任何帮助表示赞赏。

4

3 回答 3

1

首先,unlink("127.0.0.1");这里是完全错误的,不要那样做。

然后,您有两台计算机通过某个网络连接。两者都应该有 IP 地址。在客户端和服务器中替换127.0.0.1服务器的 IP 地址。服务器不必事先知道客户端的地址——它会从accept(2)调用中获取该信息。客户端需要服务器的地址才能知道连接的位置。服务器需要自己的bind(2)呼叫地址。

于 2011-08-10T21:07:20.840 回答
1

主要问题是您将 AI_PASSIVE 放入客户端代码中。AI_PASSIVE 仅适用于服务器(这就是它的信号)。

同样在服务器端,您首先应该不调用 unlink。这仅适用于 AF_UNIX 套接字,而不适用于 AF_INET。其次,您不需要将“127.0.0.1”放在服务器端的 getaddrinfo 行中。最好使用 NULL 绑定到所有可用地址。

如果您更改这些内容,我相信您的代码应该可以工作。但是,您实际上应该使用 ai_next 指针循环 getaddrinfo 结果,并尝试使用成功的第一个结果连接到每个结果。

于 2011-08-10T21:08:19.980 回答
0

Connection Refused通常意味着您的客户收到了RST他的SYN. 这通常是由于您尝试连接的端口上的服务器上缺少侦听套接字引起的。

  1. 运行你的服务器
  2. 在 CLI 上,键入netstat -ant. LISTEN您是否在端口上看到处于状态的条目?

就像是:

tcp4       0      0  *.3689                 *.*                    LISTEN  

我打赌你没有,因此你的服务器监听套接字有问题。我也打赌你在这一行所做的改变:

if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {

不太对。尝试将0.0.0.0服务器上的 IP 更改为告诉它绑定到系统上的任何 IP。在客户端,该行应该有服务器的 IP 地址。您还应该删除unlink()服务器中的调用;不必要。

如果您确实有一个监听套接字,那么您的盒子之间可能有防火墙或其他东西阻止了 SYN。尝试service iptables stop在两个系统的 CLI 上键入。

于 2011-08-10T21:11:25.640 回答