c - getpeername() 不会返回正确的端口,但会返回正确的远程主机套接字地址 C 语言

标签 c sockets tcp p2p

我想问一下 getpeername() 函数,因为它返回数据,如标题所述。我试图直接从 accept() 函数中获取值,结果也一样。端口的值似乎随机出现,即使地址的值是正确的(地址是 127.0.0.1 因为我在唯一的机器上运行多进程)。 getpeername() 的返回码为 0(状态 = 0)。我正在使用 gcc 版本 4.8.1。我写了一个没有服务器的 peer 2 peer 聊天应用程序。以下是我的代码:

struct sockaddr_in addr;
socklen_t addr_len;
int tempPort, serverSockfd;
char test[100];

// Get serverSockfd successfully....
serverSockFd = initializeSock(PORT) // In this function I initialize socket(), bind() and listen(), serverSockFd is returned by the value of socket() 


addr_len = sizeof addr;
newSock = accept(serverSockfd, (struct sockaddr *)&addr, &addr_len);
tempPort = ntohs(addr.sin_port);
inet_ntop(AF_INET, &(addr.sin_addr), test, sizeof test);

printf("tempPort\t%d\n", tempPort);
printf("test\t%s\n", test);

addr_len = sizeof addr; 
if ((status = getpeername(newSock, (struct sockaddr *) &addr, &addr_len)) != 0){  
  printf("getpeername() error!\n");
}

tempPort = ntohs(addr.sin_port);
inet_ntop(AF_INET, &(addr.sin_addr), test, sizeof test);

printf("tempPort\t%d\n", tempPort);
printf("test\t%s\n", test);    

非常感谢您的评论。这是 initializeSock() 中的部分代码:

sd = socket(AF_INET, SOCK_STREAM, 0);

if(sd < 0)
{
  perror("SocketInit(): socket() error!\n");
  exit(1);
}

ret_val = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char*) &flag, sizeof(flag));
if(ret_val == -1)
{
  perror("SocketInit(): setsockopt(SO_REUSEADDR) error!\n");
  exit(1);
}


gethostname(hostname,100);
host_entry = gethostbyname(hostname);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)*host_entry->h_addr_list));

ret_val = bind(sd, (struct sockaddr*) &addr, sizeof(addr));

if(ret_val == -1)
{
  perror("SocketInit(): bind() error!\n");
  printf("For port:%d\n",port);
  exit(1);
}
....
return sd;

这是连接到节点的服务器部分的代码。 ConnectSock(对等端口):

sd = socket(AF_INET, SOCK_STREAM, 0);  

if(sd < 0)
{
  perror("ConnectToServer(): socket() error!\n");
  exit(1);
}

if (port != 0) {

addr.sin_family = AF_INET;
addr.sin_port = htons(portOfPeerA);
addr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)*host_entry->h_addr_list));

// Do I need to bind() the port of peer B when it would like to connect to peer A? 

ret_val = connect(sd, (struct sockaddr*)&addr, sizeof(addr)); 
if(ret_val == -1)
{
  printf("Error connect());
  exit(1);
}
...

最佳答案

我不知道你从对等点接受哪个端口,但如果对等点连接到你的服务器(例如,然后一个调用接受)它将从(或多或少)随机端口连接,这就是 TCP 的工作原理。仅当对等方在连接前明确绑定(bind)到该端口时,它才会从固定端口连接。

这意味着,对等始发端口不是在服务器端(您的代码片段的来源)定义的,而是在客户端定义的(调用连接的那一端,您只连接但不绑定(bind))。

但是,请注意,如果客户端和服务器都使用固定的 IP 和端口,那么重复连接可能会出现问题,因为那样您将在 TCP 中获得相同的 4-tupel,它定义重复连接的连接,从而进入所有这些麻烦都与各种 TIME_WAIT 状态有关。所以最好让客户端只选择一个可用的端口,而不是强制它使用特定的端口。

关于c - getpeername() 不会返回正确的端口,但会返回正确的远程主机套接字地址 C 语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23033865/

相关文章:

c++ - #define函数的多重定义

java.net.SocketException : Socket is closed while socket is still open

sockets - BSD 套接字的文件描述符错误

Android/Iphone 套接字通信

c - 当我使用 '' 关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收 "control-c"

c - 共享内存和 unix domain socket 同步,不重复 shm 内容

c - 如何将文件中的数据保存到数组中

c - mpi 在结构中发送/接收多个可变长度数组

c - 如何在编译时获取初始化列表中的元素总数?

tcp - 了解 SOCKS5 协议(protocol) RFC