socket编程之bind()函数使用示例详解

 更新时间:2022年10月13日 15:43:09   作者:蝉沐风  
这篇文章主要为大家介绍了socket编程之bind()函数使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

当你创建了socket之后,你会想要把这个socket和你本机上的某个端口号(port)进行关联。

端口号是内核用来确认将收到的数据包交给哪个具体进程的socket descriptor的依据。

通常在写服务端程序的时候我们才需要进行关联,客户端程序不需要我们手动绑定端口,直接connect()就好了。

端口号具体是怎么绑定

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

sockfdsocket()返回的一个socket file descriptormy_addr是一个指向包含了你的端口号和IP地址信息的struct sockaddr指针;addrlen是以字节为单位的地址长度。

接下来,我们给出一个例子,它将socket和我本机的3490端口进行绑定:

struct addrinfo hints, *res;
int sockfd;
// first, load up address structs with getaddrinfo():
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;  // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;     // fill in my IP for me
getaddrinfo(NULL, "3490", &hints, &res);
// make a socket:
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
// bind it to the port we passed in to getaddrinfo():
bind(sockfd, res->ai_addr, res->ai_addrlen);

通过使用AI_PASSIVE标识,程序会自动绑定它所在的程序的IP。如果你想精确绑定到本机的某一个IP地址,你就不能用AI_PASSIVE了,而且你还得把getaddrinfo()的第一个参数从NULL改为你想绑定的那个IP地址。

bind()和其他系统调用一样,发生错误的时候返回-1,并且会设置全局变量errno的值。

很多老代码都会在调用bind()之前手动封装 struct sockaddr_in 。当然,这里绑定的肯定是IPv4的地址,如果你想使用IPv6,你照样可以手动封装struct sockaddr_in6 ,但是极力不推荐你这么做。你还是应该老老实实用 getaddrinfo() ,这样更优雅、更简单。

老代码

// !!! THIS IS THE OLD WAY !!!
int sockfd;
struct sockaddr_in my_addr;
sockfd = socket(PF_INET, SOCK_STREAM, 0);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT);     // short, network byte order
my_addr.sin_addr.s_addr = inet_addr("10.12.110.57");
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr);

上面这个代码中,你依然可以把my_addr.sin_addr.s_addr设置为 INADDR_ANY ,它的作用上文提到的AI_PASSIVE一样,都会让代码自动绑定到本机IP。 INADDR_ANY 的IPv6版本是一个全局变量,叫in6addr_any,这个变量会被指定给你的 struct sockaddr_in6sin6_addr字段。

你也可以使用IN6ADDR_ANY_INIT这个宏来初始化变量

调用bind()时有一件事需要你特别注意:不要使用1024以下的端口号,因为这些端口号是被保留使用的,除非你是超级管理员。除了1024以下的,1025~65535之间的随便用(其他程序占用的除外)。

有时候,你明明重新运行了你的服务端程序,但是bind()报错了,提示你“Address already in use”。这是为什么?理论上重启之后端口就会被释放啊!好吧,这是因为有一些连接到socket的连接还悬在内核中,就是它们占用了这个端口号。

端口被占用的问题解决

你可以等一分钟左右让它们自行消失,或者在你的代码加这么几行:

int yes=1;
//char yes='1'; // Solaris people use this
// lose the pesky "Address already in use" error message
if (setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof yes) == -1) {
    perror("setsockopt");
    exit(1);
} 

这样就不会再出现端口被占用的问题了。

以上就是socket编程之bind()函数使用示例详解的详细内容,更多关于socket编程bind函数的资料请关注脚本之家其它相关文章!

相关文章

  • C++中move的使用及说明

    C++中move的使用及说明

    这篇文章主要介绍了C++中move的使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • C语言运用函数的递归实现汉诺塔

    C语言运用函数的递归实现汉诺塔

    递归(recursive)函数是“自己调用自己”的函数,无论是采用直接或间接调用方式。间接递归意味着函数调用另一个函数(然后可能又调用第三个函数等),最后又调用第一个函数。因为函数不可以一直不停地调用自己,所以递归函数一定具备结束条件
    2022-07-07
  • Visual Studio 2019配置qt开发环境的搭建过程

    Visual Studio 2019配置qt开发环境的搭建过程

    这篇文章主要介绍了Visual Studio 2019配置qt开发环境的搭建过程,本文图文并茂给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C++ Primer中&、*符号的多重定义与int *p和int* p的区别讲解

    C++ Primer中&、*符号的多重定义与int *p和int* p的区别讲解

    今天小编就为大家分享一篇关于C++Primer中&、*符号的多重定义与int *p和int* p的区别讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • C++二分法在数组中查找关键字的方法

    C++二分法在数组中查找关键字的方法

    这篇文章主要介绍了C++二分法在数组中查找关键字的方法,涉及C++数组查找算法的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-09-09
  • 聊聊C语言中sizeof运算符的一个陷阱

    聊聊C语言中sizeof运算符的一个陷阱

    在C语言中,sizeof()是一个判断数据类型或者表达式长度的运算符,下面这篇文章主要给大家介绍了关于C语言中sizeof运算符的一个陷阱的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • 如何用C++求两个数的最大公约数和最小公倍数

    如何用C++求两个数的最大公约数和最小公倍数

    最大公约数是指两个或多个整数共有约数中,最大的一个约数,常用的方法是欧几里得算法,也叫辗转相除法,下面这篇文章主要给大家介绍了关于如何用C++求两个数的最大公约数和最小公倍数的相关资料,需要的朋友可以参考下
    2023-01-01
  • C语言实现简易网络聊天室

    C语言实现简易网络聊天室

    这篇文章主要为大家详细介绍了C语言实现简易网络聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • 详解C++编程中数组的基本用法

    详解C++编程中数组的基本用法

    这篇文章主要介绍了C++编程中数组的基本用法,包括数组的初始化等基本知识,需要的朋友可以参考下
    2016-01-01
  • C++ STL 内 std::{bind/tuple/function} 简单实现

    C++ STL 内 std::{bind/tuple/function} 简单实现

    这篇文章主要介绍了C++ STL 内 std::{bind/tuple/function} 简单实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02

最新评论