在带有套接字程序的C中,我试图在 server 套接字中插入getpeername()和getsockname,以在服务器端打印服务器套接字和客户端套接字的IP地址。注意:我的服务器套接字使用INADDR_ANY。我把getpeername()和getsockname()放在不同的位置:
1 / bind()之前:客户端和服务器套接字的IP地址均为0.0.0.0
2 / bind()之后:同样,客户端和服务器套接字的IP地址均为0.0.0.0
3 / accept()之后:客户端的IP地址为10.0.2.15,而服务器套接字仍为0.0.0.0
他们正确吗?在这种情况下,您能否解释为什么我得到0.0.0.0而不是特定地址?
注意:在我看来,我应该在bind()之后获得服务器套接字的特定IP地址,因为bind()已经将服务器套接字绑定到特定的IP地址。对于accept()之后,我认为客户端套接字和服务器套接字也应该是特定的IP地址,而不是0.0.0.0
答案 0 :(得分:0)
我无法重现您的问题;例如考虑
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly ApplicationDbContext _appDbContext;
private readonly UserManager<IdentityUser> _userManager;
public ValuesController(UserManager<IdentityUser> userManager, ApplicationDbContext appDbContext)
{
_userManager = userManager;
_appDbContext = appDbContext;
}
[HttpPost]
public async Task<IActionResult> Post()
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
AppUser user = new AppUser();
user.Email = "email@mail.co.uk";
user.FirstName = "mark";
user.LastName = "Macneill";
user.UserName = "Saints22";
await _userManager.CreateAsync(user, "P4$$word");
return new OkObjectResult("Account created");
}
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
}
通过#include <unistd.h>
#include <netinet/ip.h>
#include <sys/socket.h>
int main(void)
{
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = 0,
.sin_addr = { INADDR_ANY },
};
int fd;
int c_fd;
struct sockaddr_in p_addr;
socklen_t a_len = sizeof p_addr;
fd = socket(AF_INET, SOCK_STREAM, 0);
bind(fd, (void const *)&addr, sizeof addr);
getpeername(fd, (void *)&p_addr, &a_len);
getsockname(fd, (void *)&p_addr, &a_len);
listen(fd, 10);
c_fd = accept(fd, NULL, NULL);
getpeername(c_fd, (void *)&p_addr, &a_len);
getsockname(c_fd, (void *)&p_addr, &a_len);
}
运行它并连接到绑定地址,显示
strace
在您的情况1 + 2中,没有服务器,$ strace ./a.out
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getpeername(3, 0x7ffdcf3af130, [16]) = -1 ENOTCONN (Transport endpoint is not connected)
getsockname(3, {sa_family=AF_INET, sin_port=htons(60093), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0
listen(3, 10) = 0
accept(3, NULL, NULL) = 4
getpeername(4, {sa_family=AF_INET, sin_port=htons(35048), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(60093), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
将失败,并显示getpeername()
。
在ENOTCONN
之前,accept()
返回getsockname
,因为您正在听0.0.0.0
。
但是在INADDR_ANY
之后,accept()
将返回本地地址。