关于独占端口

原创 2000年08月24日 17:44:00
关于独占端口
作者:Star
2000.6.12
欢迎转载,请注明出处.

--------------------------------------------------------------------------------

不知道各位有没有安装新的for 2K的PlatformSDK啊,如果安装后,不妨比较一下一些头文件和VS98原有的头文件的异同,会发现不少有趣的东东喔!有些内容其实MS早就在之前的平台上就提供了支持,只不过一直没有写入它的头文件里去,下面就是在WinSock2.h里发现的一个例子:

在新版的WinSock2.h里,多了这么一段定义:

#define SO_EXCLUSIVEADDRUSE ((int)(~SO_REUSEADDR)) /* disallow local address reuse */

从MS的注释也可以看出来了,这个东东是为了防止本地端口被重用的,我们知道,本来我们是可以向同一个端口绑定两个Socket的,只要使用上面被“反”掉的那个选项SO_REUSEADDR就可以了,想想看这会发生什么事?我们可以在一个程序打开POP3端口(服务器端缺省是110,客户端应该设置为随机选择)收信的同时,运行自己的程序,绑定自己的Socket到同样的端口上,这时侯你就可以在该程序收信的同时,窃听到信件的内容,包括账户密码!看起来非常简单,不是吗?可是现实中很多软件并没有采取任何有效的策略来对付这一手,比如国内著名的某电邮客户端软件F**Mail.

那么我们该怎么防止这种情形在自己的程序运行当中出现?直接的想法是实时监控本机连接,看看都有些什么端口被绑定了,如果发现窃听程序存在立刻断开。听起来不错,可是真等你断开连接时可能密码已经泄漏了,要确保在密码传输前切断连接,需要大量的实时处理工作,就算抛开这些困难不谈,在Windows平台下去访问一大堆的注册表内容来确定目前活动的端口就有够烦了。还好,现在有了上面的这个socket选项,一切就变得简单了,请看如下演示程序:




//Test.cpp : Test exclusive with sockets
//if it's ok then written by Star, else i don't know^_^
//

#include
#include

//if have no the new PlatformSDK, then u need to add the
//define statement to your sourcecode, else remove it
//
#define SO_EXCLUSIVEADDRUSE ((int)(~SO_REUSEADDR))

const u_short EXCLUSIVE_PORT = 110;//or others

void main(int argc, char* argv[])
{
    SOCKET sock1, sock2;
    int ret;
    BOOL val;
    WSADATA ws;
    struct sockaddr_in in;

    //need WinSock 2.0!
    if (WSAStartup (2, &ws))
        return;

    if (LOBYTE (ws.wVersion) - 2)
        return;

    //make two sockets
    sock1 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    sock2 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);

    val = TRUE;
    ret = setsockopt (sock1, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, //set to exclusive
                      (LPCSTR)&val, 4);

    if (ret)
    {
        //failed....
        //do something to clear the error....
        return;
    }    

    ZeroMemory (&in, sizeof(in));
    in.sin_family = AF_INET;
    in.sin_port = htons (EXCLUSIVE_PORT);
    in.sin_addr.s_addr = INADDR_ANY;

    printf ("Now to bind the first socket to port %d with SO_EXCLUSIVEADDRUSE/n", EXCLUSIVE_PORT);

    if (bind (sock1, (const struct sockaddr*)&in,  sizeof(in)))
    {
        //failed...
        //do something to clear the error...
        closesocket (sock1);
        return;
    }

    printf ("The first socket has been bound to port %d/n", EXCLUSIVE_PORT);    

    ret = setsockopt (sock2, SOL_SOCKET, SO_REUSEADDR,//try to reuse
                      (LPCSTR)&val, 4);

    if (ret)
    {
        //failed....
        //do something to clear the error....
        return;
    }

    ZeroMemory (&in, sizeof(in));
    in.sin_family = AF_INET;
    in.sin_port = htons (EXCLUSIVE_PORT);
    in.sin_addr.s_addr = INADDR_ANY;

    printf ("/nNow to bind the second socket to port %d/n", EXCLUSIVE_PORT);

    if (bind (sock2, (const struct sockaddr*)&in,  sizeof(in)))
    {
        if (WSAEADDRINUSE == GetLastError ())
            printf ("bind failed, the SO_EXCLUSIVEADDRUSE take effect!/n");
        else
        {
            //failed...
            //do something to clear the error...
        }
    }        
    else
        printf ("What??? I see nothing!!!/n");

    closesocket (sock1);
    closesocket (sock2);

    return;
}     



上面的代码在我的PNT4SP6下编译运行通过,注意除了几个显眼处,很多地方都缺少应有的错误检测,需要用的朋友自己加上吧。9X下的情况我就不很清楚了,毕竟没用已经一年了,快忘光了:-)知道的朋友还请告诉我:-)我会补在后面的:-)


--------------------------------------------------------------------------------

灌水之作,敬请笑纳^_^

关于Internet Programming我也是新手,这篇东东在lu0兄的多次追问下写出来的,所以内容比较垃圾一些...现在我还记得lu0兄问我写了什么东西时的语气:“当时lu0兄的火气距离化成言辞冲出他的喉咙只差0.01公分,但是一天零一夜之后它将永远的憋在里面,因为我决定灌一篇水到这个版面上来。虽然本人生平灌过无数篇水,但是这篇,我认为是最纯净的。”

多个程序共享同一串口数据的实现

有过串口编程经验的人都知道,串口是独占方式使用的,即有且只有一个应用实例能对一个串口进行打开、读写操作。但实际应用中,我们可能要在多个应用程序中对来自同一个串口的数据进行分析。利用虚拟串口(VSPD如...
  • hitwhzhongqiu
  • hitwhzhongqiu
  • 2015年01月24日 18:14
  • 4187

关于独占端口

2000年08月24日 17:44:00 关于独占端口作者:Star2000.6.12欢迎转载,请注明出处.------------------------------------------...
  • softart
  • softart
  • 2007年10月27日 06:55
  • 162

关于端口(port)的一点理解

端口—物理端口(又称“接口”,例如计算机的I/O端口,可见。) —虚拟端口(计算机,路由或交换机内的端口,不可见) 根据提供服务类型,虚拟端口分为: ...
  • JingwenCai
  • JingwenCai
  • 2017年02月03日 23:13
  • 237

端口重用SO_REUSEADDR 和端口独占 SO_EXCLUSIVEADDRUSE

1.传输层使用不同协议的两个进程,如一个使用tcp,一个使用udp,则不用设置SO_REUSEADDR,两个进程都会绑定同一ip同一port成功,而且会自动区分收到的网络包是发给哪个进程的。 2.对...
  • qiuxin315
  • qiuxin315
  • 2013年02月20日 12:25
  • 2111

多线程独占资源的处理

#include #include using namespace std; HANDLE hMutex; DWORD WINAPI fun(LPVOID ip){ while (1) ...
  • woshizfs
  • woshizfs
  • 2014年04月30日 10:05
  • 960

进程、线程独占与共享的内容

来源自我的博客 http://www.yingzinanfei.com/2017/02/17/jinchengxianchengduzhanyugongxiangdeneirong/线程共享的内容...
  • yingzinanfei
  • yingzinanfei
  • 2017年02月17日 12:01
  • 472

C# 独占方式打开 Access

最近使用C#连接Access, 总有讨厌的ldb文件. 不喜欢, 如何去掉呢. 看了下独占模式就可以去掉. 网上搜了搜, 都是相互抄一大片... 没有一个能用的. 只好去微软官网上...
  • dingding3224
  • dingding3224
  • 2015年10月13日 14:35
  • 531

线程独占笔记

  线程同步中的双重检查:    在对一个非同步成员变量进行访问时,如果调用者发现读到了非法成员变量的时候,可以采取相应的措施。这样的措施之一就是在同步的环境下重新访问这个成员变量,判断一下它的最新值...
  • blueheart20
  • blueheart20
  • 2007年05月09日 10:08
  • 697

解除文件的独占锁定

解除文件的独占锁定,通过ZwQuerySystemInformation查询当前系统的所有句柄信息, 然后调用OpenProcess获取目标进程句柄,遍历当前所有进程, 根据进程ID, 得到此进程打开...
  • Reversess
  • Reversess
  • 2014年07月27日 10:53
  • 598

CreateFile 独占打开文件

小唐,独占打开文件,其它文件再也无法打开,实现代码如下#include int main(int argc, char* argv[]) { HANDLE file_handle; file_h...
  • chinafe
  • chinafe
  • 2013年05月15日 17:11
  • 4071
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于独占端口
举报原因:
原因补充:

(最多只允许输入30个字)