习惯于通过套接字本地端口 [英] Get Local Port used by Socket

查看:192
本文介绍了习惯于通过套接字本地端口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要得到一个(客户端)使用套接字的本地端口。

这是我的理解是 Windows套接字执行隐式绑定函数调用,所以 getsockname()的sendto()应提供分配的端口。然而,它总是将0作为端口号。我缺少的东西吗?

例如:

 如果(SENDTO(的sockfd,...)!= SOCKET_ERROR)
    的printf(已发送\\ n);如果(getsockname(的sockfd,(结构sockaddr *)及罪恶,和放大器;!sinlen)= SOCKET_ERROR)
    的printf(端口=%U \\ N,还有ntohs(sin.sin_port);
其他
    的printf(错误);//结果:发送,端口= 0


解决方案

我可以在例如code看到的唯一歧义是什么大小分配给 sinlen 之前调用。如果你正在使用的 winsock的 ,它应该被定义,并分配 INT sinlen = sizeof的(罪);

我用我的系统上这个code,并返回我连接通过端口一个非零值:

 结构SOCKADDR_IN罪。
INT LEN = sizeof的(罪);
如果(getsockname(袜子,(结构sockaddr *)及罪恶,和放大器; LEN)== -1)
    //处理错误
其他
    的printf(端口号%d个\\ N,还有ntohs(sin.sin_port));

顺便说一句,在 ntohs和功能 函数返回主机字节顺序的值。如果[ sin.sin_port ]已在主机字节顺序,那么这个功能将扭转它。它是由 [你] 的应用程序,以确定是否字节顺序必须扭转。 [文字括号内为我的重点]

在回答注释问题( getsockname()

的函数原型 getsockname()

  INT getsockname(
  标签:APIWinHTTP插座S,
  _Out_结构sockaddr *的名字,
  _Inout_为int * namelen // INT,不socklen_t的
);

有关更多讨论的 socklen_t的

修改(地址可能的方法来重新设置插座无需重新启动电脑。)结果
如果的Winsock API调用停止工作predictably,您可以通过使用 的WSAStartup WSACleanup (看到链接的WSAStartup的底部code为例)

I need to get the local port used by a (client) socket.

It was my understanding that Windows Sockets performs an implicit bind function call, therefore getsockname() after sendto() should provide the assigned port. However, it always sets 0 as the port number. Am I missing something?

ex:

if (sendto(sockfd, ...) != SOCKET_ERROR)
    printf("Sent\n");

if (getsockname(sockfd, (struct sockaddr*)&sin, &sinlen) != SOCKET_ERROR)
    printf("port = %u\n", ntohs(sin.sin_port);
else
    printf("Error");

//result: Sent, port = 0

解决方案

The only ambiguity I can see in your example code is what size you assigned to sinlen before calling. (you do not show it) If you are using winsock, it should be defined, and assigned int sinlen = sizeof(sin);

I used this code on my system, and it returns a non-zero value for the port I am connecting through:

struct sockaddr_in sin;
int len = sizeof(sin);
if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
    //handle error
else
    printf("port number %d\n", ntohs(sin.sin_port));    

By the way, The ntohs function function returns the value in host byte order. If [ sin.sin_port ] is already in host byte order, then this function will reverse it. It is up to [your] application to determine if the byte order must be reversed. [text in brackets are my emphasis]

In answer to comment question ( getsockname() ):

The function prototype for getsockname():

int getsockname(
  _In_    SOCKET          s,
  _Out_   struct sockaddr *name,
  _Inout_ int             *namelen  //int, not socklen_t
);

For more discussion on socklen_t

Edit (address possible approach to re-setting sockets without rebooting PC.)
If winsock API calls cease to work predictably, you can re-start sockets without rebooting the PC by using WSAStartup and WSACleanup (see code example at bottom of link for WSAStartup)

这篇关于习惯于通过套接字本地端口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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