ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:328.61KB ,
资源ID:7846840      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7846840.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(linux网络编程之绑定端口注意事项及端口复用.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

linux网络编程之绑定端口注意事项及端口复用.docx

1、linux网络编程之绑定端口注意事项及端口复用Linux网络编程之绑定端口注意事项及端口复用所谓绑定(bind)是指别人连接我只能通过我所绑定的端口,相当于,我买了一个手机,别人要想联系我,必须要知道我的手机号码,这时候,我需要怎么办呢?我需要给手机插上电话卡,固定一个电话号码,这样别人就能通过这个电话号码联系我。手机插上电话卡,固定一个电话号码,类似于绑定(bind)的过程,绑定(bind)为了固定一个端口号,别的网络程序就可以找到这个端口号,找到这个端口号就能找到这个端口号所对应的网络应用程序。在网络编程里,通常都是在服务器里绑定(bind)端口,这并不是说客户端里不能绑定(bind)端口

2、,但这里需要注意的是,一个网络应用程序只能绑定一个端口( 一个套接字只能 绑定一个端口 )。一个套接字不能同时绑定多个端口,如下:#include #include #include #include #include #include #include intmain(intargc,charchar*argv) charserver_ip30=10.221.20.12; intsockfd; sockfd=socket(AF_INET,SOCK_DGRAM,0);/创建UDP套接字 if(sockfd0) perror(socket); exit(-1); /初始化本地网络信息 struc

3、tsockaddr_inmy_addr; bzero(&my_addr,sizeof(my_addr); my_addr.sin_family=AF_INET; my_addr.sin_port=htons(8000); my_addr.sin_addr.s_addr=htonl(INADDR_ANY); /第一次绑定端口8000 interr_log; err_log=bind(sockfd,(structsockaddr*)&my_addr,sizeof(my_addr); if(err_log!=0) perror(bind8000); close(sockfd); exit(-1);

4、/又一次绑定别的端口9000,会绑定失败 my_addr.sin_port=htons(9000); err_log=bind(sockfd,(structsockaddr*)&my_addr,sizeof(my_addr); if(err_log!=0) perror(bind9000); close(sockfd); exit(-1); close(sockfd); return0; 程序编译运行后结果如下:如果客户端想绑定端口号,一定要调用发送信息函数之前绑定( bind )端口,因为在发送信息函数( sendto, 或 write ),系统会自动给当前网络程序分配一个随机端口号,这相当

5、于随机绑定了一个端口号,这里只会分配一次,以后通信就以这个随机端口通信,我们再绑定端口号的话,就会绑定失败。如果我们放在发送信息函数( sendto, 或 write )之前绑定,那样程序将以我们绑定的端口号发送信息,不会再随机分配一个端口号。绑定失败例子( UDP )如下:#include #include #include #include #include #include #include intmain(intargc,charchar*argv) charserver_ip30=10.221.20.12; intsockfd; sockfd=socket(AF_INET,SOCK_

6、DGRAM,0);/创建UDP套接字 if(sockfd0) perror(socket); exit(-1); structsockaddr_indest_addr; bzero(&dest_addr,sizeof(dest_addr); dest_addr.sin_family=AF_INET; dest_addr.sin_port=htons(8080);/服务器的端口 inet_pton(AF_INET,server_ip,&dest_addr.sin_addr); charsend_buf512=thisisfortest; /如果前面没有绑定端口,sendto()系统会随机分配一个

7、端口 sendto(sockfd,send_buf,strlen(send_buf),0,(structsockaddr*)&dest_addr,sizeof(dest_addr);/发送数据 /初始化本地网络信息 structsockaddr_inmy_addr; bzero(&my_addr,sizeof(my_addr); my_addr.sin_family=AF_INET; my_addr.sin_port=htons(8000); my_addr.sin_addr.s_addr=htonl(INADDR_ANY); /sendto()后面绑定端口,绑定失败 interr_log;

8、err_log=bind(sockfd,(structsockaddr*)&my_addr,sizeof(my_addr); if(err_log!=0) perror(bind8000); close(sockfd); exit(-1); close(sockfd); return0; 程序编译运行后结果如下:在上面提到:一个网络应用程序只能绑定一个端口( 一个套接字只能绑定一个端口 )。实际上,默认的情况下,如果一个网络应用程序的一个套接字 绑定了一个端口( 占用了 8000 ),这时候,别的套接字就无法使用这个端口( 8000 ), 验证例子如下:#include #include #i

9、nclude #include #include #include #include intmain(intargc,charchar*argv) intsockfd_one; interr_log; sockfd_one=socket(AF_INET,SOCK_DGRAM,0);/创建UDP套接字one if(sockfd_one0) perror(sockfd_one); exit(-1); /设置本地网络信息 structsockaddr_inmy_addr; bzero(&my_addr,sizeof(my_addr); my_addr.sin_family=AF_INET; my_a

10、ddr.sin_port=htons(8000);/端口为8000 my_addr.sin_addr.s_addr=htonl(INADDR_ANY); /绑定,端口为8000 err_log=bind(sockfd_one,(structsockaddr*)&my_addr,sizeof(my_addr); if(err_log!=0) perror(bindsockfd_one); close(sockfd_one); exit(-1); intsockfd_two; sockfd_two=socket(AF_INET,SOCK_DGRAM,0);/创建UDP套接字two if(sockf

11、d_two0) perror(sockfd_two); exit(-1); /新套接字sockfd_two,继续绑定8000端口,绑定失败 /因为8000端口已被占用,默认情况下,端口没有释放,无法绑定 err_log=bind(sockfd_two,(structsockaddr*)&my_addr,sizeof(my_addr); if(err_log!=0) perror(bindsockfd_two); close(sockfd_two); exit(-1); close(sockfd_one); close(sockfd_two); return0; 程序编译运行后结果如下:那如何让

12、sockfd_one, sockfd_two两个套接字都能成功绑定8000端口呢?这时候就需要要到端口复用了。端口复用允许在一个应用程序可以把 n 个套接字绑在一个端口上而不出错。设置socket的SO_REUSEADDR选项,即可实现端口复用:intopt=1; /sockfd为需要端口复用的套接字 setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(constvoidvoid*)&opt,sizeof(opt);SO_REUSEADDR可以用在以下四种情况下。 (摘自Unix网络编程卷一,即UNPv1)1、当有一个有相同本地地址和端口的socket1处于T

13、IME_WAIT状态时,而你启动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可以测试这种情况。3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。这和2很相似,区别请看UNPv1。4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的多播,不用于TCP。需要注意的是,设置端口复用函数要在绑定之前调用,而且只要绑定到同一个端

14、口的所有套接字都得设置复用:/sockfd_one,sockfd_two都要设置端口复用 /在sockfd_one绑定bind之前,设置其端口复用 intopt=1; setsockopt(sockfd_one,SOL_SOCKET,SO_REUSEADDR,(constvoidvoid*)&opt,sizeof(opt); err_log=bind(sockfd_one,(structsockaddr*)&my_addr,sizeof(my_addr); /在sockfd_two绑定bind之前,设置其端口复用 opt=1; setsockopt(sockfd_two,SOL_SOCKET,

15、SO_REUSEADDR,(constvoidvoid*)&opt,sizeof(opt); err_log=bind(sockfd_two,(structsockaddr*)&my_addr,sizeof(my_addr);端口复用完整代码如下:#include #include #include #include #include #include #include intmain(intargc,charchar*argv) intsockfd_one; interr_log; sockfd_one=socket(AF_INET,SOCK_DGRAM,0);/创建UDP套接字one if

16、(sockfd_one0) perror(sockfd_one); exit(-1); /设置本地网络信息 structsockaddr_inmy_addr; bzero(&my_addr,sizeof(my_addr); my_addr.sin_family=AF_INET; my_addr.sin_port=htons(8000);/端口为8000 my_addr.sin_addr.s_addr=htonl(INADDR_ANY); /在sockfd_one绑定bind之前,设置其端口复用 intopt=1; setsockopt(sockfd_one,SOL_SOCKET,SO_REUS

17、EADDR, (constvoidvoid*)&opt,sizeof(opt); /绑定,端口为8000 err_log=bind(sockfd_one,(structsockaddr*)&my_addr,sizeof(my_addr); if(err_log!=0) perror(bindsockfd_one); close(sockfd_one); exit(-1); intsockfd_two; sockfd_two=socket(AF_INET,SOCK_DGRAM,0);/创建UDP套接字two if(sockfd_two0) perror(sockfd_two); exit(-1)

18、; /在sockfd_two绑定bind之前,设置其端口复用 opt=1; setsockopt(sockfd_two,SOL_SOCKET,SO_REUSEADDR, (constvoidvoid*)&opt,sizeof(opt); /新套接字sockfd_two,继续绑定8000端口,成功 err_log=bind(sockfd_two,(structsockaddr*)&my_addr,sizeof(my_addr); if(err_log!=0) perror(bindsockfd_two); close(sockfd_two); exit(-1); close(sockfd_one

19、); close(sockfd_two); return0; 端口复用允许在一个应用程序可以把 n 个套接字绑在一个端口上而不出错。同时,这 n 个套接字发送信息都正常,没有问题。但是,这些套接字并不是所有都能读取信息,只有最后一个套接字会正常接收数据。下面,我们在之前的代码上,添加两个线程,分别负责接收sockfd_one,sockfd_two的信息:#include #include #include #include #include #include #include #include /线程1的回调函数 voidvoid*recv_one(voidvoid*arg) printf(=

20、recv_one=n); intsockfd=(int)arg; while(1) intrecv_len; charrecv_buf512=; structsockaddr_inclient_addr; charcli_ipINET_ADDRSTRLEN=;/INET_ADDRSTRLEN=16 socklen_tcliaddr_len=sizeof(client_addr); recv_len=recvfrom(sockfd,recv_buf,sizeof(recv_buf),0,(structsockaddr*)&client_addr,&cliaddr_len); inet_ntop(

21、AF_INET,&client_addr.sin_addr,cli_ip,INET_ADDRSTRLEN); printf(nip:%s,port:%dn,cli_ip,ntohs(client_addr.sin_port); printf(sockfd_one=data(%d):%sn,recv_len,recv_buf); returnNULL; /线程2的回调函数 voidvoid*recv_two(voidvoid*arg) printf(+recv_two+n); intsockfd=(int)arg; while(1) XX文库 - 让每个人平等地提升自我intrecv_len; charrecv_buf512=; structsockaddr_inclient_addr; charcli_ipINET_ADDRSTRLEN=;/INET_ADDRSTRLEN=16 socklen_tcliaddr_len=sizeof(client_addr)

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1