无线局域网上的TCP套接字

无线局域网上的TCP套接字,tcp,ip-address,bsd,sockets,Tcp,Ip Address,Bsd,Sockets,我有一个项目,它使用TCP套接字在服务器和客户端之间进行通信。到目前为止,我已经在一台计算机上完成了这项工作,所以我刚刚使用了本地地址“127.0.0.1”作为绑定和连接两侧的地址,并且工作正常。现在我有了第二台计算机作为客户端,但我不知道如何相应地更改地址。它们通过未连接到Internet的网络连接。在代码看起来像这样之前- 服务器- struct addrinfo hints; struct addrinfo *servinfo; //will point to the results

我有一个项目,它使用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提示;
结构addrinfo*服务信息//将指出结果
//存储连接地址和大小
结构sockaddr\u存储它们的地址;
袜子的地址和尺寸;
memset(提示和提示,0,提示大小)//确保结构为空
hits.ai_family=AF_INET//本地地址
hits.ai_socktype=SOCK_流//tcp
hits.ai_flags=ai_被动//使用本地主机地址
//获取服务器信息,放入服务信息
if((status=getaddrinfo(“127.0.0.1”、端口、提示和服务信息))!=0){
fprintf(标准,“getaddrinfo错误:%s\n”,gai_strerror(状态));
返回false;
}
//制作插座
fd=套接字(servinfo->ai_系列,servinfo->ai_socktype,servinfo->ai_协议);
如果(fd<0){
printf(“\n服务器套接字故障%m”,错误号);
返回false;
}
//允许重用端口
int yes=1;
if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*)&是,sizeof(int))=-1){
perror(“setsockopt”);
返回false;
}
//解绑
取消链接(“127.0.0.1”);
如果(绑定(fd,servinfo->ai_地址,servinfo->ai_地址)<0){
printf(“\n绑定错误%m”,错误号);
返回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;
}
struct addrinfo提示;
结构addrinfo*服务信息//将指出结果
memset(提示和提示,0,提示大小)//确保结构为空
hits.ai_family=AF_INET//本地地址
hits.ai_socktype=SOCK_流//tcp
hits.ai_flags=ai_被动//使用本地主机地址
//获取服务器信息,放入服务信息
if((status=getaddrinfo(“127.0.0.1”、端口、提示和服务信息))!=0){
fprintf(标准,“getaddrinfo错误:%s\n”,gai_strerror(状态));
返回false;
}
//制作插座
fd=套接字(servinfo->ai_系列,servinfo->ai_socktype,servinfo->ai_协议);
如果(fd<0){
printf(“\n服务器套接字故障%m”,错误号);
返回false;
}
//连接
如果(连接(fd,servinfo->ai_地址,servinfo->ai_地址)<0){
printf(“\n客户端连接失败%m”,错误号);
返回false;
}
我知道这应该很简单,但我不知道如何更改IP使其工作。我尝试在这些行的引号中设置服务器计算机的IP地址- if((status=getaddrinfo(“127.0.0.1”、端口、提示和服务信息))!=0) 及 取消链接(“127.0.0.1”)

然后将客户端代码中的地址更改为该行中客户端计算机的IP地址- if((status=getaddrinfo(“127.0.0.1”、端口、提示和服务信息))!=0)

每当我这样做,它告诉我连接被拒绝。我还尝试了相反的方法,将服务器的地址放在客户机的行中,将客户机的地址放在服务器的行中,以及其他一些尝试。在这一点上,我觉得我只是在猜测。那么,有人能帮助我理解如何将本地地址从一台计算机改为连接两台计算机吗?感谢您的帮助。

首先,
取消链接(“127.0.0.1”)在这里是完全错误的,不要这样做


然后,你有两台计算机通过网络连接。两者都应该有IP地址。将
127.0.0.1
替换为服务器在客户端和服务器中的IP地址。服务器不必事先知道客户机的地址——它将从调用中获得该信息。客户端需要服务器的地址才能知道连接到哪里。服务器需要自己的呼叫地址。

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

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


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

连接被拒绝
通常意味着您的客户端收到了一个到其
SYN
RST
。这通常是由于服务器上以及您尝试连接的端口上缺少侦听套接字造成的

  • 运行您的服务器
  • 在CLI上,键入
    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。尝试在两个系统的CLI上键入
    服务iptables stop

    什么是IP?你能把他们分开吗?你确定没有防火墙吗?服务器ip为192.168.2.4,客户端ip为192.168.43.16。不过我还没有想到防火墙。顺便问一下,如果这很重要的话,我正在使用ubuntu。那么客户端的ip地址对客户端有什么用呢?什么都没有?当向服务器发送数据包时,客户端内核将使用它作为源地址。另外,请查看Per的答案-您不需要<