socket端口复用问题一二
实际上,默认的情况下,如果一个网络应用程序的一个套接字 绑定了一个端口( 占用了 8000 ),这时候,别的套接字就无法使用这个端口( 8000 ), 验证例子如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd_one;
int err_log;
sockfd_one = socket(AF_INET, SOCK_DGRAM, 0); //创建UDP套接字one
if(sockfd_one < 0)
{
perror("sockfd_one");
exit(-1);
}
// 设置本地网络信息
struct sockaddr_in my_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);
// 绑定,端口为8000
err_log = bind(sockfd_one, (struct sockaddr*)&my_addr, sizeof(my_addr));
if(err_log != 0)
{
perror("bind sockfd_one");
close(sockfd_one);
exit(-1);
}
int sockfd_two;
sockfd_two = socket(AF_INET, SOCK_DGRAM, 0); //创建UDP套接字two
if(sockfd_two < 0)
{
perror("sockfd_two");
exit(-1);
}
// 新套接字sockfd_two,继续绑定8000端口,绑定失败
// 因为8000端口已被占用,默认情况下,端口没有释放,无法绑定
err_log = bind(sockfd_two, (struct sockaddr*)&my_addr, sizeof(my_addr));
if(err_log != 0)
{
perror("bind sockfd_two");
close(sockfd_two);
exit(-1);
}
close(sockfd_one);
close(sockfd_two);
return 0;
}
程序编译运行后结果如下:
那如何让sockfd_one, sockfd_two两个套接字都能成功绑定8000端口呢?这时候就需要要到端口复用了。端口复用允许在一个应用程序可以把 n 个套接字绑在一个端口上而不出错。
设置socket的SO_REUSEADDR选项,即可实现端口复用:
int opt = 1;
// sockfd为需要端口复用的套接字
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt));
SO_REUSEADDR可以用在以下四种情况下。 (摘自《Unix网络编程》卷一,即UNPv1)
1、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。
2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可以测试这种情况。
3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。这和2很相似,区别请看UNPv1。
4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的多播,不用于TCP。
需要注意的是,设置端口复用函数要在绑定之前调用,而且只要绑定到同一个端口的所有套接字都得设置复用:
// sockfd_one, sockfd_two都要设置端口复用
// 在sockfd_one绑定bind之前,设置其端口复用
int opt = 1;
setsockopt( sockfd_one, SOL_SOCKET,SO_REUSEADDR, (const void *)&opt, sizeof(opt) );
err_log = bind(sockfd_one, (struct sockaddr*)&my_addr, sizeof(my_addr));
// 在sockfd_two绑定bind之前,设置其端口复用
opt = 1;
setsockopt( sockfd_two, SOL_SOCKET,SO_REUSEADDR,(const void *)&opt, sizeof(opt) );
err_log = bind(sockfd_two, (struct sockaddr*)&my_addr, sizeof(my_addr));
socket端口复用问题一二的更多相关文章
- 【 socke】C# socket端口复用-多主机头绑定
什么是端口复用: 因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分.这种多重绑定便称之为端口复用 ...
- 在C#中实现Socket端口复用
转载:http://www.csharpwin.com/csharpspace/68.shtml 一.什么是端口复用: 因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在 ...
- 转载:C# socket端口复用-多主机头绑定
什么是端口复用: 因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分.这种多重绑定便称之为端口复用 ...
- Socket端口复用
在网络应用中(如Java Socket Server),当服务关掉立马重启时,很多时候会提示端口仍被占用(因端口上有处于TIME_WAIT的连接).此时可通过 SO_REUSEADDR 参数( soc ...
- 端口复用技术简单了解;重用端口;socket复用端口
端口复用相关点 多个应用复用端口,只有最后一个绑定的socket可以接受数据,所有socket都可以发送数据 使用端口复用技术时,所有的socket都开启端口复用,才可以实现端口复用 黑客技术,使用标 ...
- Linux:TCP状态/半关闭/2MSL/端口复用
TCP状态 CLOSED:表示初始状态. LISTEN:该状态表示服务器端的某个SOCKET处于监听状态,可以接受连接. SYN_SENT:这个状态与SYN_RCVD遥相呼应,当客户端SOCKET执行 ...
- TCP套接字端口复用SO_REUSEADDR
下面建立的套接字都是tcp套接字 1.进程创建监听套接字socket1,邦定一个指定端口,并接受了若干连接.那么进程创建另外一个套接口socket2,并试图邦定同一个端口时候,bind错误返回“Add ...
- Netscaler的超高端口复用助力应对公网地址紧张
Netscaler的超高端口复用助力应对公网地址紧张 http://blog.51cto.com/caojin/1898351 经常会有人问一个IP只有65535(姑且不考虑预留端口),从Big-ip ...
- TCP端口复用引发的异常,用setsockopt来解决
TCP端口复用引发的异常,用setsockopt来解决 我们在并发连接一个服务端时候他会出现这种情况 OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允 ...
随机推荐
- Ubuntu 16.04安装测试MQTT Mosquitto
环境:Ubuntu 16.04 介绍MQTT MQTT是一种机器到机器的消息传递协议,旨在为“物联网”设备提供轻量级的发布/订阅通信.它通常用于地理跟踪车队,家庭自动化,环境传感器网络和公用事业规模数 ...
- 【AppScan】入门工作原理详解
AppScan,即 AppScan standard edition.其安装在 Windows 操作系统上,可以对网站等 Web 应用进行自动化的应用安全扫描和测试.Rational AppScan( ...
- SSIS教程:创建简单的ETL包 -- 4. 增加错误处理流程(Adding Error Flow Redirection)
为了处理在转换过程中可能发生的错误,MicrosoftIntegration Services 允许根据每个组件和每个列来决定如何处理无法转换的数据. 可以选择忽略某些列中的失败.重定向整个失败的行或 ...
- C# 文件上传 制作水印
其实C#的文件上传是非常简单的 前台代码 <asp:FileUpload ID="FileUpload1" accept=".jpg,.png,.jpeg" ...
- [linux] shell脚本编程-xunsearch安装脚本学习
安装脚本setup.sh #!/bin/sh # FULL fast install/upgrade script # See help message via `--help' # $Id$ # s ...
- Spring Boot 概述
spring boot 的功能: 1.自动配置 2.起步依赖 3.Actuator hello word: http://start.spring.io 中按需生产spring boot项目,然后倒入 ...
- Ora-03113\Ora-03114与Oracle In 拼接字符串的问题
刚深入接触Oracle不久(大学里以及刚参加工作时学到的Oracle知识只能算是皮毛),因为之前使用SqlServer有将近两年的时间,对SqlServer相对来说很熟悉,比较而言,Oracle真心很 ...
- java设计模式-观察者模式,装饰者模式
1.1定义 慨念:定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. 即:主题和观察者定义了一对多的关系,观察者依赖于主题,只要主题发生变化,观察者就 ...
- Java中返回值的详解
package com.company; //java中main()函数中调用其他方法的两种方式//1.实例化对象 public class returnDemo { public static vo ...
- [HNOI2006]最短母串问题
题目大意:给定一个字符串集,求一个最短字串,使得该集合内的串都是该串的一个子串 算法:AC自动机+最短路+状压DP 注意空间限制 #include"cstdio" #include ...