Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么服务器套接字提供与绑定端口号不同的端口号?_C_Sockets_Network Programming_Endianness - Fatal编程技术网

C 为什么服务器套接字提供与绑定端口号不同的端口号?

C 为什么服务器套接字提供与绑定端口号不同的端口号?,c,sockets,network-programming,endianness,C,Sockets,Network Programming,Endianness,我正在用C编写一个小的套接字程序。在服务器端,我使用socket()系统调用创建一个套接字描述符,然后将该套接字与一个端口绑定。在此之后,我尝试获取描述符的IP/端口号,它给出的端口号与绑定端口号没有区别。我尝试使用getsockname()方法获取IP/端口号,使用此方法正确吗?请帮帮我 #define SERVER_ADDR "127.0.0.1" #define SERVER_PORT "9090" // actual port no I am binding #define QUEUE_

我正在用C编写一个小的套接字程序。在服务器端,我使用socket()系统调用创建一个套接字描述符,然后将该套接字与一个端口绑定。在此之后,我尝试获取描述符的IP/端口号,它给出的端口号与绑定端口号没有区别。我尝试使用getsockname()方法获取IP/端口号,使用此方法正确吗?请帮帮我

#define SERVER_ADDR "127.0.0.1"
#define SERVER_PORT "9090" // actual port no I am binding
#define QUEUE_LENGTH 10

int main()
{
struct addrinfo hints, *servinfo, *temp;

memset(&hints,0,sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

// here I am passing SERVER_PORT == 9090
int status = getaddrinfo(SERVER_ADDR,SERVER_PORT,&hints,&servinfo);
if(status != 0)
{
printf("Server: getaddrinfo() errored with code %d\n",status);
return;
}

int sfd = -1;
for(temp = servinfo; temp != NULL; temp = servinfo->ai_next)
{
sfd = socket(temp->ai_family,temp->ai_socktype,temp->ai_protocol);
if(sfd == -1)
{
  printf("Server: Socket error with code %d\n",sfd);
  continue;
}

status = bind(sfd,temp->ai_addr,temp->ai_addrlen);
if(status == -1)
{
  printf("Server: Bind error with code %d\n",status);
  continue;
}
printf("Server: Bind Successful\n");

// un necessary code goes here
struct sockaddr_in server_address;
char ipv4[INET_ADDRSTRLEN];
int addr_size = sizeof(server_address);
// i am using below method to get the port no from socket descriptor
getsockname(sfd, (struct sockaddr *)&server_address, &addr_size);

// I am expecting below will print 9090. but it prints different port no why ? 
printf("Server Port: %d\n",server_address.sin_port);
printf("Port from getsddrinfo: %d\n",( (struct sockaddr_in *)temp->ai_addr)->sin_port);

inet_ntop(AF_INET, &(server_address.sin_addr),ipv4,INET_ADDRSTRLEN);
printf("Server IP Address: %s\n",ipv4);
// un necessary code ends here
break;
}

if(temp == NULL)
{
printf("Server: Failed to bind\n");
return;
}
status = listen(sfd,QUEUE_LENGTH);
if(status == -1)
{
printf("Server: Listening failed\n");
return;
}
printf("Server: waiting for coneections...\n");

while(1)
{
printf("Server: Main loop, will wait for client to connect...\n");
struct sockaddr client_address;
int addr_length = sizeof client_address;
// accepting client
int new_sfd = accept(sfd,&client_address,&addr_length); 
}
printf("Server: Done!\n"); 
}
输出为:

Server: Bind Successful
Server Port: 33315 --> why this different from one I have binded (9090)
Port from getsddrinfo: 33315 --> why this different from one I have binded (9090)
Server IP Address: 127.0.0.1
Server: waiting for coneections...
Server: Main loop, will wait for client to connect...

添加
hints.sin_port=htons(9090)
after
hints.ai_socktype=SOCK_STREAM

结构sockaddr的十进制成员以网络字节顺序返回


因此,您需要使用
ntoh
函数族将这些值转换为主机字节顺序,然后再使用它们进行打印。

这不应该
for(temp=servinfo;temp!=NULL;temp=servinfo->ai_next)
读取
for(temp=servinfo;temp!=NULL;temp->ai_next)
您是正确的,即使修改后,我仍然得到不同的端口号。谢谢。请正确地输入您的代码,很难像这样阅读。对不起,我是stackoverflow新手,这是我的第一个问题,我以后会正确地处理。感谢alk:-)在OP的上下文中,在
提示中设置端口是没有意义的,因为它将被
getaddrinfo()
覆盖。我假设
getaddrinfo()
已经使用正确的字节顺序(网络)填充了
hits
的成员。哦,我在getservbyname()中想,sorryhits是
struct addrinfo'的类型,没有直接成员。正如alk告诉我们的那样,getaddrinfo()将按网络字节顺序填充服务信息的成员。可能类似于
((struct sockaddr_in*)servinfo->ai_addr)->sin_port=htons(9090);`。我说得对吗?你说得对,Sinu port是struct sockaddr_的直接成员,在
getaddrinfo()
中,它接受主机和服务(对于IP4,即:主机名或其IP地址和端口号,都是ASCII表示形式),返回一个或多个已填充的
struct addrinfo
以传递到
bind()
(服务器端)或者
connect()
(客户端)。我将print语句更改为
printf(“服务器端口:%d\n”,ntohs(服务器地址.sin\u端口)),现在我得到了正确的端口号9090。非常感谢你的帮助@DhanarajDurairaj:一定要接受这个答案,这样alk就可以获得学分。@Remy Lebeau:根据alk的答案,只有我在我的程序中做了更改。我不明白你的意思?@DhanarajDurairaj:如果alk的答案解决了你的问题,那么就把它标记为被接受的答案,这样他就可以得到适当的声誉分数。