假如端口被socket使用过,并且利用socket.close()来关闭连接,但此时端口还没有释放,要经过一个TIME_WAIT的过程之后才能使用。为了实现端口的马上复用,可以选择setsockopt()函数来达到目的。

python:
import socket
tcp1=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp1.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
tcp1.bind('1.1.1.1',12345)

此为tcp的例子,udp一样

c:
s = socket(AF_INET, SOCK_STREAM, 0);
/* What you need to do is add the following two line to your code */
unsigned value = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(valu

e));
/* Then do other things */
listen(s, SOMAXCONN);
/* ... */
写Socket程序的时候经常会遇到这个问题:如果自己的程序不小心崩溃了,重新启动程序的时候往往会在bind调用上失败,错误原因为Address
Already In
Use,往往要等待两分钟才能再次绑定。但是在很多的程序(比如nginx)中好像并不存在这个问题,就算被KILL了也能立刻重启。这个区别还是比较头
痛的。
其实我猜Unix Socket编程
样的书上有讨论过这方面的问题,不过我竟然没有这方面的书籍(完全靠man看来也是行不通啊)。我曾经天真的以为,在收到SIGTERM这样的信号的时候
把所有套接字全部关闭可以解决问题。后来才发现无济于事。Google了这方面的文章才知道,解决这个问题理论上有三种办法。
1.SOCK_REUSEADDR:曾经在研究内网穿透的时候跟这个东西打过交道。如果一个监听的套接字被设置为允许地址复用,那么套接字绑定到的地址不
会被独占,所以必然不会存在Address already in
use的问题。而且如果有两个套接字绑定到同一个端口,也只允许一个套接字进行监听,后一个套接字在调用listen的时候会报错。因此这个方案显然是最
佳方案。对于完全不知道我在说什么的童鞋,你们只要这么做
s = socket(AF_INET, SOCK_STREAM, 0);
/* What you need to do is add the following two line to your code */
unsigned value = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
/* Then do other things */listen(s, SOMAXCONN);/* ... */
2.不过据说这样的做法容易产生安全性问题,某些操作系统(没有指明Linux
是BSD或是Windows)允许分别属于两个进程的两个套接字绑定到两个地址的同一个端口。大多数程序把套接字绑定到0.0.0.0这个地址上进行监听
(也即监听所有网络设备),这种情形下另外一个进程可以绑定到127.0.0.1或者是其他网络设备的IP地址的同一个端口,并进行监听,就可能把外部的
连接给拦截下来(因为127.0.0.1这样的IP是属于特定设备的,比0.0.0.0这虚拟设备更specific)。
而解决这个安全性的问题的方法其实也不难(其实换个没问题的操作系统就可以了不是?),只要把套接字绑定绑定到具体的网络设备的IP地址(比如绑定到
127.0.0.1,或者a.b.c.d)即可,大不了为每个网络设备建一个套接字。如果实施起来有难度,只能考虑后面的两种方法。
3.让客户端先关闭连接。如果所有的连接关闭事件都在客户端首先发生,那么也不会存在这个问题。不过这种做法可能需要修改协议,而且貌似很容易恶意连接攻击。修改系统TCP超时时间,这种方法很不推荐。

原文:http://www.2cto.com/kf/201208/150347.html

[转] c和python利用setsockopt获得端口重用的更多相关文章

  1. python利用setsockopt获得端口重用

    server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) 假如端口呗socket使用过,并且利用socket.close()来关闭连接,但此时端口还没有释放,要经过一个 ...

  2. python程序—利用socket监控端口

    利用socket监控服务器端口,端口不通时,发邮件提醒 import yagmail #导入yagmail模块 import re #导入re模块,进行正则匹配 import socket #导入so ...

  3. [Python] 利用Django进行Web开发系列(二)

    1 编写第一个静态页面——Hello world页面 在上一篇博客<[Python] 利用Django进行Web开发系列(一)>中,我们创建了自己的目录mysite. Step1:创建视图 ...

  4. python利用or在列表解析中调用多个函数.py

    python利用or在列表解析中调用多个函数.py """ python利用or在列表解析中调用多个函数.py 2016年3月15日 05:08:42 codegay & ...

  5. python 利用 ogr 写入shp文件,数据格式

    python 利用 ogr 写入 shp 文件, 定义shp文件中的属性字段(field)的数据格式为: OFTInteger # 整型 OFTIntegerList # 整型list OFTReal ...

  6. python 自动发现Java端口

    python 自动发现Java端口 #!/usr/bin/env python #encoding: utf8 import subprocess try: import json except Im ...

  7. Python利用pandas处理Excel数据的应用

    Python利用pandas处理Excel数据的应用   最近迷上了高效处理数据的pandas,其实这个是用来做数据分析的,如果你是做大数据分析和测试的,那么这个是非常的有用的!!但是其实我们平时在做 ...

  8. python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie)

    python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie) 主要包括两部分内容:(1)利用python中的dict实现Trie:(2) ...

  9. 使用Python编写简单的端口扫描器的实例分享【转】

    转自 使用Python编写简单的端口扫描器的实例分享_python_脚本之家 http://www.jb51.net/article/76630.htm -*- coding:utf8 -*- #!/ ...

随机推荐

  1. css改变谷歌浏览器的滚动条样式

    详细内容请点击 /*---滚动条默认显示样式--*/ ::-webkit-scrollbar-thumb{        height:50px;    outline-offset:-2px;   ...

  2. WebApi授权拦截——重写AuthorizeAttribute

        跟mvc一样,webapi大多通过附加Authorize特性来实现授权,Authorize当授权失败时返回状态码:401.一般系统状态为401时,服务端就Redirect重定向到登录页.   ...

  3. 计算日期时间 自动加1天 PHP计算闰年 java与PHP时间戳对比区别

    昨天写一个同步数据库的模块  从一个数据库同步到另外一个数据库,因为数据较多,不可能一次性全部搬迁过去,所以就按照每天搬迁! 写了一个 模块,点击加1,只要点击一次,自动从A数据库取出1天的数据, 并 ...

  4. JS函数式编程【译】2.2 与函数共舞

  5. hdu 1318 Palindromes(回文词)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1318 题意分析:输入每行包含一个字符串,判断此串是否为回文串或镜像串. 表面上看这道题有些复杂,如果能 ...

  6. QT 信号与槽连接

    转帖 http://www.cnblogs.com/cnhome/archive/2009/10/01/1577277.html 信号(SIGNAL)和槽(SLOT)是Qt编程的一个重要部分.这个机制 ...

  7. PSP编程初探 Hello World

    自己有一台PSP2000,玩了这么长时间的游戏,所以打算去探究一下PSP这个平台的程序的构建方式. 在网上搜了很多资料,感觉能用上的不多,毕竟这太小众了,通过自己的探索,总结了一下. 先搭建MinGW ...

  8. Windows Phone 8.1开发:如何从ListView中,获取ScrollViewer对象

    在使用ListView作为信心呈现载体开发应用程序时,我们经常需要通过监视滚动条(ScrollViewer)的位置状态来完成一些交互逻辑.最直接的体现就是 延时加载,(上滑加载更多,下拉获取更新数据) ...

  9. jQuery遮罩层的实现

    遮罩层其实就是一个占据整个页面的半透明效果的页面元素,一般用div实现.页面中实现遮罩层,无非就是为了让用户只能操作弹出窗口的内容,而不允许操作弹出窗口外的内容. 在实现时,我使用了两个div,一个遮 ...

  10. Linux磁盘与文件系统概念理解

    磁盘级别概念     这里讲的主要是网上所谓的老式磁盘,它是由一个个盘片组成的,我们先从个盘片结构讲起.如图1所示,图中的一圈圈灰色同心圆为一条条磁道,从圆心向外画直线,可以将磁道划分为若干个弧段,每 ...