如何获得接受绑定套接字的IP地址? [英] How to get the ip address of the accepted in-bound socket?

查看:748
本文介绍了如何获得接受绑定套接字的IP地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是:

Server将创建一个套接字,绑定到特定端口和地址= INADDR_ANY。

听()及接受()的新的连接。然后,我们可以获取客户端的IP地址

从accept()方法。

现在,我想知道服务器的IP地址,因为服务器的主机有

这是它的多个NIC。

如何知道与该接受绑定插座是?网络接口的IP地址

我试过getsockname,它给我的端口号,但​​IP是全零。

更新:这里是code:

Server.c(头文件被删除)

  INT主要(无效)
{    结构SOCKADDR_IN stSockAddr;
    INT资源,addr_len,SocketFD,ConnectFD;    结构sockaddr_in的地址;    SocketFD =插座(PF_INET,SOCK_STREAM,IPPROTO_TCP);    如果(-1 == SocketFD)
    {
      PERROR(无法创建套接字);
      //退出(EXIT_FAILURE);
      返回-1;
    }    memset的(安培; stSockAddr,0,sizeof的stSockAddr);
    stSockAddr.sin_family = AF_INET;
    stSockAddr.sin_port = htons(49335);
    stSockAddr.sin_addr.s_addr = INADDR_ANY;    如果(-1 ==绑定(SocketFD,(结构sockaddr *)及stSockAddr,sizeof的stSockAddr))
    {
      PERROR(错误绑定失败);
      关闭(SocketFD);
     返回-1;
    }
    的printf(要听\\ n!);
    如果(-1 ==听(SocketFD,10))
    {
      PERROR(错误听失败);
      关闭(SocketFD);
      //退出(EXIT_FAILURE);
      返回-1;
    }    ConnectFD =接受(SocketFD,NULL,NULL);        如果(0 GT; ConnectFD)
        {
                PERROR(错误接受失败);
                关闭(SocketFD);
                //退出(EXIT_FAILURE);
                返回-1;
        }    addr.sin_family = AF_INET;
    RES = getsockname(ConnectFD,(结构sockaddr *)及地址,和放大器; addr_len);
    //如果你删除以下评论,这意味着,如果你调用
    // getsockname的两倍,其结果将是正确的。
    //解析度= getsockname(ConnectFD,(结构sockaddr *)及地址,和放大器; addr_len);    的printf(地址:%x \\ n,addr.sin_addr.s_addr);    而(1){
        如果(的getchar()=='Q')
                        打破;
    }    关闭(ConnectFD);
    关闭(SocketFD);
    返回0;
}

下面是client.c:

  INT主要(无效)
{    结构SOCKADDR_IN stSockAddr;    中期业绩;    INT SocketFD =插座(PF_INET,SOCK_STREAM,IPPROTO_TCP);    如果(-1 == SocketFD)
    {
      PERROR(无法创建套接字);
      出口(EXIT_FAILURE);
    }    memset的(安培; stSockAddr,0,sizeof的stSockAddr);    stSockAddr.sin_family = AF_INET;
    stSockAddr.sin_port = htons(49335);
    RES = inet_pton(AF_INET,192.168.1.102,&安培; stSockAddr.sin_addr);    如果(0> RES)
    {
      PERROR(错误:第一个参数是不是一个有效的地址族);
      关闭(SocketFD);
      出口(EXIT_FAILURE);
    }
    否则,如果(0 == RES)
    {
      PERROR(字符的字符串(第二个参数不包含有效的ip地址);
      关闭(SocketFD);
      出口(EXIT_FAILURE);
    }    如果(-1 ==连接(SocketFD,(结构sockaddr *)及stSockAddr,sizeof的stSockAddr))
    {
      PERROR(连接失败);
      关闭(SocketFD);
      出口(EXIT_FAILURE);
    }    / *执行读写操作... * /
    的printf(客户端的sockfd成功\\ n);      而(1){          如果(的getchar()=='Q')
              打破;      }
    关机(SocketFD,SHUT_RDWR);    关闭(SocketFD);
    返回0;
}


解决方案

使用 getsockname(2)返回插座接受(2) 的绑定从返回插槽(2)

My question is:

Server will create a socket, bind to a given port and with address = INADDR_ANY.

listen() & accept() the new connection. Then, we can get the client's ip-address

from accept().

Now, I want to know the ip-address of the Server, since the host of the server has

multiple NIC on it.

How to know the ip-address of the network interface with which the accepted in-bound socket is from?

I tried getsockname, it gave me the port number, but the ip is all-zero.

Update: Here is the code:

Server.c (header files are removed)

int main(void)
{

    struct sockaddr_in stSockAddr;
    int res, addr_len, SocketFD, ConnectFD;

    struct sockaddr_in addr;

    SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(-1 == SocketFD)
    {
      perror("can not create socket");
      //exit(EXIT_FAILURE);
      return -1;
    }

    memset(&stSockAddr, 0, sizeof stSockAddr);
    stSockAddr.sin_family = AF_INET;
    stSockAddr.sin_port = htons(49335);
    stSockAddr.sin_addr.s_addr = INADDR_ANY;

    if(-1 == bind(SocketFD,(struct sockaddr *)&stSockAddr, sizeof stSockAddr))
    {
      perror("error bind failed");
      close(SocketFD);
     return -1;
    }


    printf("going to listen!\n"); 
    if(-1 == listen(SocketFD, 10))
    {   
      perror("error listen failed");
      close(SocketFD);
      //exit(EXIT_FAILURE);
      return -1; 
    }   

    ConnectFD = accept(SocketFD, NULL, NULL);

        if(0 > ConnectFD)
        {   
                perror("error accept failed");
                close(SocketFD);
                //exit(EXIT_FAILURE);
                return -1; 
        }   

    addr.sin_family = AF_INET;
    res = getsockname (ConnectFD, (struct sockaddr *)&addr, &addr_len);
    // if you remove the following comment, that means, if you call 
    // two times of getsockname, the result will be correct.
    //res = getsockname (ConnectFD, (struct sockaddr *)&addr, &addr_len);

    printf("addr:%x\n", addr.sin_addr.s_addr);

    while(1) {
        if (getchar() == 'q')
                        break;
    }

    close(ConnectFD);
    close(SocketFD);
    return 0;
}

Below is client.c:

int main(void)
{

    struct sockaddr_in stSockAddr;

    int Res;

    int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (-1 == SocketFD)
    {
      perror("cannot create socket");
      exit(EXIT_FAILURE);
    }

    memset(&stSockAddr, 0, sizeof stSockAddr);

    stSockAddr.sin_family = AF_INET;
    stSockAddr.sin_port = htons(49335);
    Res = inet_pton(AF_INET, "192.168.1.102", &stSockAddr.sin_addr);

    if (0 > Res)
    {
      perror("error: first parameter is not a valid address family");
      close(SocketFD);
      exit(EXIT_FAILURE);
    }
    else if (0 == Res)
    {
      perror("char string (second parameter does not contain valid ipaddress");
      close(SocketFD);
      exit(EXIT_FAILURE);
    }

    if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof stSockAddr))
    {
      perror("connect failed");
      close(SocketFD);
      exit(EXIT_FAILURE);
    }

    /* perform read write operations ... */
    printf("client sockfd is successful\n"); 

      while(1) {

          if (getchar() == 'q')
              break;

      }


    shutdown(SocketFD, SHUT_RDWR);

    close(SocketFD);
    return 0;
}

解决方案

Use getsockname(2) on the socket returned from accept(2), not the socket returned from bind(2).

这篇关于如何获得接受绑定套接字的IP地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆