• Windows网络编程笔记5 -- 其他套接字


      包括红外线套接字(IrSock)、IPX/SPX 套接字、NetBIOS 套接字、AppleTalk 套接字、ATM 套接字等。对这些套接字进行简单介绍。

    第一、红外线套接字(I r S o c k)

      头文件  #include”af_irda.h” ,函数定义等都在这里面,可以研究一下这个文件。

      地址结构

    //结构类型
    typedef struct _SOCKADDR_IRDA {
      u_short irdaAddressFamily;//红外线接口地址家族   AF_IRDA
      u_char  irdaDeviceID[4];//设备的ID
      char    irdaServiceName[25];//服务名
    } SOCKADDR_IRDA, *PSOCKADDR_IRDA, *LPSOCKADDR_IRDA;

    这里说一下如何获取附近的红外线设备

    1 //如何获取附近的红外线设备
    2 DEVICELIST devList;//
    3 DWORD dwListLen = sizeof(DEVICELIST);
    4 SOCKET sock = WSASocket(AF_IRDA,SOCK_STREAM,0,NULL,0;WSA_FLAG_OVERLAPPED);//
    5 devList.numDevice = 0;
    6 DWORD deRet   = getsockopt(sock,SOL_IRLMP,ITLMP_ENUMDEVICES,(char*)&devlist,&dwListLen);//获取sock配置情况

    其中函数getsockopt()是一个很重要的函数,如

    1 //获取套接字的配置情况
    2 int getsockopt(
    3   SOCKET s,//套接字标识
    4 int level,// 选项定义的层次。支持的层次仅有SOL_SOCKET和IPPROTO_TCP
    5   int optname,// 需获取的套接口选项
    6   char *optval,// 指向存放所获得选项值的缓冲区
    7   int *optlen//指向optval缓冲区的长度值。
    8 );

    红外线服务器建立过程

      1) 建立一个地址家族AF_IRDA套接字和套接字类型SOCK_STREAM。

      2)用服务器的服务名填写一个SOCKADDR_IRDA结构。

      3)利用套接字句柄和SOCKADDR_IRDA结构调用bind。

      4)利用套接字句柄和backlog边限调用listen。

      5)为接入客户机锁定一个accept调用。

    红外线客户机建立过程

      1) 建立地址家族AF_IRDA套接字和套接字类型SOCK-STREAM。

      2)调用有IRLMP_ENUM_DEVICES选项的getsockopt函数,列举所有可用的红外线设备。

      3)针对返回的每个设备,利用设备ID和准备连接的服务名填写一个SOCKADDR_IRDA结构。

      4)利用套接字句柄和SOCKADDR_IRDA结构,调用connect函数。针对步骤3)中所填的结构,重复步骤4),直到连接成功。

     创建套接字如下,其他的操作和一般的socket一样

        SOCKETs=socket(AF_IRDA,SOCK_STREAM,0);

        SOCKETs2=WSASocket(AF_IRDA,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);

    第二,IPX/SPX 套接字

      “互联网包交换”(IPX)协议是一个常见协议,一般为承担NovellNetWare客户机/服务器联网服务的计算机所用。IPX提供两个进程间的无连接通信。IPX是一种无连接通信。

      IPX网络、网段是用IPX路由器桥接在一起的。每个网段分配4字节的唯一地址号。当更多的网段桥接在一起时,IPX路由器管理网段之间的通信,每个网段有唯一的网段号。IPX用套接字号来区分一个节点上的通信。

      要用IPX进行Winsock客户机或服务器通信,必须建立SOCKADDR_IPX结构。该结构在Wsipx.h头文件中定义,应用程序在包括Winsock2.h文件之后还必须包括该文件。

    //ipx地址结构
    typedef struct sockaddr_ipx {
        short sa_family;//地址家族
        char  sa_netnum[4];//网段号
        char  sa_nodenum[6];//物理地址
        unsigned short sa_socket;//套接字或者接口
    } SOCKADDR_IPX, *PSOCKADDR_IPX,FAR *LPSOCKADDR_IPX;

    创建套接字

    //创建套接字,IPX是一种无连接通信
    SOCKET s1 = socket(AF_IPX, SOCK_DGRAM,NSPROTO_IPX);//第三个参数不能为0
    SOCKET s2 = WSASocket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX,NULL,0,WSA_FLAG_OVERLAPPED)

    若想建立有连接的通信,可改变参数SOCK_DGRAMSOCK_STREAMNSPROTO_SPX等。

    IPX示例:

     1 //socket.cpp
     2 //IPX/SPX 套接字
     3 #include <windows.h>
     4 #include "stdio.h"
     5 #include <Wsipx.h>
     6 
     7 #pragma comment(lib, "ws2_32.lib")
     8 
     9 void main()
    10 {
    11     //创建套接字
    12     SOCKET sdServer;
    13 //    SOCKET s2 = WSASocket(AF_IRDA,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
    14     SOCKADDR_IPX IPXAddr;
    15     int addLen = sizeof(SOCKADDR_IPX);
    16     if ((sdServer = socket(AF_IPX,SOCK_DGRAM,NSPROTO_IPX)) == INVALID_SOCKET)
    17     {
    18         printf("Socket failed with error%d
    ",WSAGetLastError());
    19         getchar();
    20         return;
    21     }
    22     //绑定套接字
    23     memset(&IPXAddr,0x00,sizeof(SOCKADDR_IPX));
    24     IPXAddr.sa_family = AF_IPX;
    25     IPXAddr.sa_socket = htons(5150);
    26     if (bind(sdServer,(PSOCKADDR)&IPXAddr,sizeof(SOCKADDR_IPX)) == SOCKET_ERROR)
    27     {
    28         printf("bind failed with error%d
    ",WSAGetLastError());
    29         getchar();
    30         return;
    31     }
    32 
    33     //获取服务名
    34     if (getsockname((unsigned)sdServer,(PSOCKADDR)&IPXAddr,&addLen) == SOCKET_ERROR)
    35     {
    36         printf("getsockname failed with error%d
    ",WSAGetLastError());
    37         getchar();
    38         return;
    39     }
    40     //打印信息
    41     printf("%s
    %s
    %s\%s",IPXAddr.sa_family,IPXAddr.sa_netnum,IPXAddr.sa_nodenum,IPXAddr.sa_socket);
    42     getchar();
    43     
    44 }

      必须保证你电脑上装有IPX协议,不然无法运行成功。

    第三、NetBIOS 套接字

      创建套接字

    //方式一
    SOCKET s = WSASocket(                AF_NETBIOS,//地址家族
    SOCK_DGRAM | SOCK_SEQPACKET,//协议类型,两个只能选择一个
    lana,//LANA编号
    NULL,//协议相关信息
    0,//组名
    WSA_FLAG_OVERLAPPED);//套接字标志

    还可以通过枚举,根据传输协议,建立套接字

    //方式2
    //根据传输协议,建立套接字
    WSAPROTOCOL_INFO lpProtocolBuf;
    DWORD dwBufLen;
    DWORD dwNum = WSAEnumProtocols(NULL,lpProtocolBuf,&dwBufLen);
    if (dwNum == SOCKET_ERROR)
    {
        printf("socket error%d
    ",WSAGetLastError());
    }
    
    for (int i = 0; i < dwNum ; i ++)
    {
        //查询地址家族
        if (lpProtocolBuf[i].iAddressFamily == AF_NETBIOS)
        {
            //查询是无连接还是面向连接的
            s[j++] = WSASocket(FROM_PROTOCOL_INFO,FROM_PROTOCOL_INFO,FROM_PROTOCOL_INFO,
                            &lpProtocolBuf[i],0,WSA_FLAG_OVERLAPPED);
        }
    }

    第四、AppleTalk 套接字

      AppleTalk名实际上是以三个独立的名字为基础的:名、类型和区。每个名字的长度可达32个字符。这个名字标识机器上的进程及其关联套接字。类型是区的子群机制。传统意义上,区是一个网络,它是由物理定位于同一个循环上、使用AppleTalk协议的计算机构成的。AppleTalk名必须是独一无二的。

      头文件   wshatalk.h   必须包含这个头文件才能使用相关的数据结构。

    //地址结构
    typedef struct sockaddr_at
    {
        USHORT    sat_family;//地址家族   AF_APPLETALK
        USHORT    sat_net;    //
        UCHAR     sat_node;    //节点
        UCHAR     sat_socket;//套接字
    } SOCKADDR_AT, *PSOCKADDR_AT;

    简单创建AppleTalk套接字

    1     //创建appletalk socket
    2     s = socket(AF_APPLETALK,SOCK_STREAM,ATPROTO_ADSP);
    3     if(s == INVALID_SOCKET)
    4     {
    5         printf("socket error : %d 
    ",WSAGetLastError());
    6         getchar();
    7         return 1;
    8     }

    如果想注册AppleTalk名,则必须保证使用三个参数,如下

    #define MY_ZONE "*"//区,当前区

    #define MY_TYPE "Winsock_app"//类型

    #define MY_OBJECT "Appletalk-server"//名

      这个AppleTalk很复杂,我暂时就不深入研究了。

    第四、ATM 套接字

      异步传输协议ATM,ATM协议没有提供流控制。它是一个面向连接的协议,要么提供消息模式,要么提供流模式。

      一个ATM网络有两个网络接口:用户网络接口(UNI)和网络节点接口(NNI)。UNI接口是在终端和ATM交换机之间建立的,而NNI接口则是在两个交换机之间建立的。

      头文件    ws2atm.h   所有的参数定义都在头文件里。

    地址结构

    typedef struct sockaddr_atm {
        u_short satm_family;         /* address family should be AF_ATM  */
        ATM_ADDRESS satm_number; /* ATM address */
        ATM_BLLI satm_blli;          /* B-LLI ,宽带高层信息*/这些高级功能暂时不说了
        ATM_BHLI satm_bhli;          /* B-HLI ,宽带基层信息*/
    } sockaddr_atm, SOCKADDR_ATM, *PSOCKADDR_ATM, *LPSOCKADDR_ATM;

    第二个参数ATM_ADDRESS 结构如下:

    #define ATM_ADDR_SIZE          20
    typedef struct {
        DWORD AddressType; /* E.164 或者 NSAP */
        DWORD NumofDigits; /*数字大小*/
        UCHAR Addr[ATM_ADDR_SIZE]; /* IA5 对应 E164(E.164), BCD 对应 NSAP(网络服务访问点)
    } ATM_ADDRESS;

     //创建ATM套接字

       SOCKETs=socket(AF_ATM,SOCK_RAW,ATMPROTO_AAL5);

      ATM 套接字是一个十六进制的ASCII字符串,由40个字符组成,与组成ATM_ADDRESS结构NSAP式或E.164地址的20个字节相对应,所以使用时需要将其转换成ATM_ADDRESS 结构,这里有一个Windows提供的函数可供转换WSAStringToAddress()。

      地址结构转换

      WSAAddressToString和WSAStringToAddress。这两个函数提供了一个与协议无关的转换方法,可以把SOCKADDR结构转换成一个格式化的字符串,反之亦然。

     1 //将sockaddr地址转换成字符串
     2 INT WSAAPI WSAAddressToString(
     3   _In_      LPSOCKADDR lpsaAddress,//特定的协议,ATM,Appletalk
     4   _In_      DWORD dwAddressLength,//sockaddr的长度
     5   _In_opt_  LPWSAPROTOCOL_INFO lpProtocolInfo,//可选参数,协议提供者
     6   _Inout_   LPTSTR lpszAddressString,//易于理解的字符串,即转换成的字符串
     7   _Inout_   LPDWORD lpdwAddressStringLength//字符串长度
     8 );
     9 
    10 
    11 //将字符串转换成sockaddr结构
    12 INT WSAAPI WSAStringToAddress(
    13   _In_      LPTSTR AddressString,//要转换的字符串
    14   _In_      INT AddressFamily,//地址家族
    15   _In_opt_  LPWSAPROTOCOL_INFO lpProtocolInfo,// 可选参数,协议提供者
    16   _Out_     LPSOCKADDR lpAddress,//sockaddr 结构指针
    17   _Inout_   LPINT lpAddressLength//sockaddr结构长度
    18 );

     

  • 相关阅读:
    关于导出Excel表中存在部门或用户数据权限问题
    进阶之路005 增删改查/数据导入导出之导出功能
    进阶之路004 增删改查/数据导入导出之查询功能
    进阶之路003 增删改查/数据导入导出之修改功能
    进阶之路002 增删改查/数据导入导出之删除功能
    进阶之路001 增删改查/数据导入导出之新增功能
    springboot常见注解 2020-01-19
    学习设计模式
    java并发
    java并发
  • 原文地址:https://www.cnblogs.com/songliquan/p/3413750.html
Copyright © 2020-2023  润新知