谁给好好讲讲 socket bind 函数

冻结 2011-10-28 12:24:55
今天忽然发现一直以来对它的理解不够深刻。
...全文
145 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
冻结 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zzcmx2008 的回复:]

UNIX网络编程(第1卷套接口API第3版)
有详细介绍啊
[/Quote]

有那本书,就在面前,刚看完。
pathuang68 2011-10-28
  • 打赏
  • 举报
回复
楼主是在散分吧。

摘要 :在套接口中,一个套接字只是用户程序与内核交互信息的枢纽,它自身没有太多的信息,也没有网络协议地址和端口号等信息,在进行网络通信的时候,必须把一个套接字与一个地址相关联,这个过程就是地址绑定的过程。许多时候内核会我们自动绑定一个地址,然而有时用户可能需要自己来完成这个绑定的过程,以满足实际应用的需要,最典型的情况是一个服务器进程需要绑定一个众所周知的地址或端口以等待客户来连接。这个事由 bind的函数完成。

从bind函数功能我们很容易推测出这个函数的需要的参数与相应的返回值,如果此时大家已经对socket接口有点熟悉了:
#include<sys/socket.h>
int bind( int sockfd, struct sockaddr* addr, socklen_t addrlen)
返回:0 ──成功, - 1 ──失败

参数sockfd
指定地址与哪个套接字绑定,这是一个由之前的socket函数调用返回的套接字。调用bind的函数之后,该套接字与一个相应的地址关联,发送到这个地址的数据可以通过这个套接字来读取与使用。
参数addr
指定地址。这是一个地址结构,并且是一个已经经过填写的有效的地址结构。调用bind之后这个地址与参数sockfd指定的套接字关联,从而实现上面所说的效果。
参数addrlen
正如大多数socket接口一样,内核不关心地址结构,当它复制或传递地址给驱动的时候,它依据这个值来确定需要复制多少数据。这已经成为socket接口中最常见的参数之一了。

bind函数并不是总是需要调用的,只有用户进程想与一个具体的地址或端口相关联的时候才需要调用这个函数。如果用户进程没有这个需要,那么程序可以依赖内核的自动的选址机制来完成自动地址选择,而不需要调用bind的函数,同时也避免不必要的复杂度。在一般情况下,对于服务器进程问题需要调用 bind函数,对于客户进程则不需要调用bind函数。

bind函数

int bind(
SOCKET s,
const struct sockaddr FAR *name,
int namelen
);

当创建了一个Socket以后,套接字数据结构中有一个默认的IP地址和默认的端口号。一个服务程序必须调用bind函数来给其绑定一个IP地址和一个特定的端口号。客户程序一般不必调用bind函数来为其Socket绑定IP地址和断口号。该函数的第一个参数指定待绑定的Socket描述符;第二个参数指定一个sockaddr结构,该结构是这样定义的:
struct sockaddr {
u_short sa_family;
char sa_data[14];
};

其中sin_family置AF_INET;sin_port指明端口号;sin_addr结构体中只有一个唯一的字段s_addr,表示IP地址,该字段是一个整数,一般用函数inet_addr()把字符串形式的IP地址转换成unsigned long型的整数值后再置给s_addr。有的服务器是多宿主机,至少有两个网卡,那么运行在这样的服务器上的服务程序在为其Socket绑定IP地址时可以把htonl(INADDR_ANY)置给s_addr,这样做的好处是不论哪个网段上的客户程序都能与该服务程序通信;如果只给运行在多宿主机上的服务程序的Socket绑定一个固定的IP地址,那么就只有与该IP地址处于同一个网段上的客户程序才能与该服务程序通信。我们用0来填充 sin_zero数组,目的是让sockaddr_in结构的大小与sockaddr结构的大小一致。下面是一个bind函数调用的例子:
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8888);
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(ListenSocket,(struct sockaddr *)&saddr,sizeof(saddr));

以上摘自:http://blog.csdn.net/dongliqiang2006/article/details/5824651
cocoabird 2011-10-28
  • 打赏
  • 举报
回复
我也想深刻了解下
zzcmx2008 2011-10-28
  • 打赏
  • 举报
回复
第三版好像没有电子版,我有第二版的电子版,需要的话可以给你
zzcmx2008 2011-10-28
  • 打赏
  • 举报
回复
而且半小时之内,就可以看差不多
zzcmx2008 2011-10-28
  • 打赏
  • 举报
回复
UNIX网络编程(第1卷套接口API第3版)
有详细介绍啊
  • 打赏
  • 举报
回复
qq120848369 2011-10-28
  • 打赏
  • 举报
回复
好比QQ服务器bind在8000端口!!!!! 难道我的客户端QQ也要bind在8000端口么?????? 我偏偏写个百度Hi客户端主动bind在8000端口,难道QQ客户端就没法用了么!!!!!!!!!!!!! 当然不!!!!!!
QQ客户端只关心QQ服务器的8000端口!!!!! QQ客户端本地端口由connect得同时让内核自动bind一个!!!!!!!!QQ客户端根本不关心本地是什么端口!!!!!!!QQ客户端的端口只有QQ服务器关心!!!!!!!!!QQ客户端connect到QQ服务器的时候,QQ服务器能够accept得知,通信没压力!!!!!!!!!

就好比你让同事帮你寄个邮件,你告诉他寄给谁,你不关心他从哪里给你寄出去。

收信的人自然知道你那个同事填的信件发送地址,自然会把信再给寄回来。
PG 2011-10-28
  • 打赏
  • 举报
回复
接分档,专业接分!
qq120848369 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 freezezdj 的回复:]
今天忽然发现一直以来对它的理解不够深刻。
[/Quote]

角色:两个机器A和B

操作:A与B进行TCP通信,A做服务器,B做客户端

如果A不bind在某个端口上,B怎么去connect服务器,没端口啊!!!!!

A bind在INADDR_ANY/12000, B就去connect A's eth0's IP/12000, 于是成功了!!!!

为什么B不bind??????????????????????????????????????? 因为内核会自动为B选择一个本地端口bind。


总结!!!!!!!!!!!!!!!!

我是电脑A的一个SOCKET,我要给B发信息,我需要知道对端地址!!! 我也需要确定一个本地地址!!!!!否则电脑B怎么知道消息回给我的哪一个端口呢!!!!!
luciferisnotsatan 2011-10-28
  • 打赏
  • 举报
回复
UNIX网络编程

lz在散分,接分了
ouyh12345 2011-10-28
  • 打赏
  • 举报
回复
当做楼主在散分了

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧