我的问题是:
服务器将创建一个套接字,绑定到给定端口并使用address = INADDR_ANY。
listen()& accept()新连接。然后,我们可以获得客户端的ip-address
来自accept()。
现在,我想知道服务器的ip-address,因为服务器的主机有
上面有多个网卡。
如何知道接受的入站套接字来自的网络接口的IP地址?
我尝试了getsockname,它给了我端口号,但ip是全零。
更新:这是代码:
Server.c(删除标题文件)
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;
}
以下是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;
}
答案 0 :(得分:9)
在从getsockname(2)
返回的套接字上使用accept(2)
,而不是从bind(2)
返回的套接字。
答案 1 :(得分:6)
getsockname()
获取传递套接字的名称。
在此示例中,您传递由创建的套接字
接受服务器中的功能。
这个套接字在服务器端,所以它的名字和&地址是
与服务器端有关。
如果您想知道“谁与我联系”
你必须使用getpeername()
而不是getsockname。
答案 2 :(得分:1)
如果你删除以下评论,那就意味着,如果你打电话 两次getsockname,结果是正确的。 res = getsockname(ConnectFD,(struct sockaddr *)& addr,& addr_len);
你必须初始化addr_len。
addr_len = sizeof(addr);