IPX编程的问题。
1,我知道大多数朋友也没做过IPX编程,所以将相关资料贴出(取自MSDN),理解错了的地方请大家帮我指明。IPX的socket结构体如下:
typedef struct sockaddr_ipx {
    short sa_family;
    char  sa_netnum[4];
    char  sa_nodenum[6];
    unsigned short sa_socket;
} SOCKADDR_IPX;
结构体说明:
sa_family :Address family AF_IPX in host order. 
Sa_netnum :IPX network identifier in network order. 
Sa_nodenum :Station node address, flushed right. 
Sa_socket :IPX socket number in network order The network number is an administrative domain and typically names a single Ethernet or token ring segment.
这是否说Sa_netnum指的是一个子网的标志,我应该如何定义它。在同一个子网内它应该是只要定义一个相同的值就可以了?
The node number is a station's physical address.
这是否说Sa_nodenum指的是机子的MAC地址?
The combination of net and node form a unique station address that is presumed to be unique in the world. 
这说明Sa_nodenum确实应该是MAC地址。The IPX socket number is a network/transport service number much like a TCP port number and is not to be confused with the Winsock socket descriptor.
其中Sa_socket起端口的作用。2。我的问题。
Sa_netnum与Sa_nodenum  决定一台机子的地址。但我不清楚这两者是如何取值的。
Sa_netnum 和 端口 sa_socket 二者是否都由自己来定义,
sa_nodenum是否由每个客户端自己先获取IP地址再调用SenARP函数来获得MAC地址赋予它?
recvfrom中的struct sockaddr FAR*参数由于sockaddr是16个字节,而sockaddr_ipx是14个字节。如何处理?以下这段具体是什么意思?
Caution  SOCKADDR_IPX is 14 bytes long and is shorter than the 16-byte sockaddr reference structure. IPX/SPX implementations may accept the 16-byte length as well as the true length. If you use SOCKADDR_IPX and a hard-coded length of 16 bytes, the implementation may assume that it has access to the 2 bytes following your structure. 
没做过,有些不清楚,烦做过IPX的高手指明,谢谢。

解决方案 »

  1.   

    Sa_netnum: 网络号你可以改的,在 WINDOWS 的 IPX 的属性里面。
    Sa_nodenum:节点地址,就是MAC地址了,是固定的。
    sa_socket : 端口号当然是自己程序指定了。sa_nodenum是否由每个客户端自己先获取IP地址再调用SenARP函数来获得MAC地址赋予它?
    ————————————————
    通常你不需要知道自己的网络号和节点地址。创建时用 0 就可以了,MSDN里面有例子的。the implementation may assume that it has access to the 2 bytes following your structure. 
    ——————————————-
    系统会假定可以访问 SOCKADDR_IPX 这个结构后面跟着的2个字节。
      

  2.   

    谢谢everandforever(Forever) ,现在清楚了许多。
    everandforever(Forever) 你说:
    通常不需要知道自己的网络号和节点地址。创建时用 0 就可以了。
    那么创建时所有客户端与服务器初始都设置为0么,或者根本就不设置它,那如何辨别各自呢?
    最终还是系统会自动为之分配,然后在发送前调用getsockname函数获知系统为之设置的网络号和接点地址。
    是不是这样?
      

  3.   

    创建时把网络号和节点地址指定为0,系统会自动设置的.创建好后你就可以取到他们的值了.关于如何取,我手头上没有代码,不过MSDN上的例子里有. 服务器端创建时唯一需要自己指定的就是端口了,就像TCP一样(客户端不需要特别指定端口号,0就行了). 客户端连接服务器时,要人工设定服务器的网络号和节点地址( 就像TCP的IP地址) 和端口号.
      

  4.   

    好,我已经弄懂了IPX编程。而且我也阅读了MSDN上的代码,正如你所说的。再次谢谢你 everandforever(Forever)。
      

  5.   

    SOCKET Server;
    SOCKADDR_IPX IpxAddr;
    int nAddrlen = sizeof(SOCKADDR_IPX); Server = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
    if (Server == INVALID_SOCKET)
    {
    TRACE1("%d\n", WSAGetLastError());
    return;
    } ZeroMemory(&IpxAddr, sizeof(SOCKADDR_IPX));
    IpxAddr.sa_family = AF_IPX;
    IpxAddr.sa_socket = htons(PORT); if (bind(Server, (PSOCKADDR)&IpxAddr, sizeof(SOCKADDR_IPX)) == SOCKET_ERROR)
    {
    TRACE1("%d\n", WSAGetLastError());
    return;
    } if (getsockname((unsigned)Server, (PSOCKADDR)&IpxAddr, &nAddrlen) == SOCKET_ERROR)
    {
    TRACE1("%d\n", WSAGetLastError());
    return;
    } DWORD dwNetNum = (DWORD)IpxAddr.sa_netnum;
    BYTE* p = (BYTE*)IpxAddr.sa_nodenum;
    TRACE("%02x.%02x.%02x.%02x\n", dwNetNum & 0xff, (dwNetNum>>8) & 0xff, (dwNetNum>>16) & 0xff, (dwNetNum>>24) & 0xff);
    TRACE("%02x.%02x.%02x.%02x.%02x.%02x\n", p[5], p[4], p[3], p[2], p[1], p[0]);