• 大开眼界:Netbios 上古时代如何用一个参数实现一个世界 负面典型


    初级代码游戏的专栏介绍与文章目录-CSDN博客

            今天的程序员普遍遵循这样的接口设计原则:通过不同的接口名和参数列表准确表达不同的功能。

            这似乎是理所当然的,然而上古时代却并非如此,比如Netbios协议整个协议的接口只有一个函数、一个参数!

            当初是基于什么原则这样设计不晓得,但它确实真真实实地存在过,最初是在windows 2000上实现的,到了windows vista就被淘汰。

            我之所以用到这个东西是为了取得局域网上的机器名,代码如下:

    1. //取得MACHNAME
    2. STATE getmachname(char * ip,char * machname,int machnamelen)
    3. {
    4. if(machnamelen<16)
    5. {
    6. return -1;
    7. }
    8. //以下使用socket
    9. hostent * phost;
    10. unsigned long addr;
    11. if(INADDR_NONE==(addr=inet_addr(ip)))
    12. return -1;
    13. if(NULL!=(phost=gethostbyaddr((char *)&addr,4,PF_INET)))
    14. {
    15. if((int)strlen(phost->h_name)>=machnamelen)
    16. return -1;
    17. else
    18. {
    19. strcpy(machname,phost->h_name);
    20. return 1;
    21. }
    22. }
    23. //以下使用NetBIOS
    24. char ncb_buffer[sizeof(ADAPTER_STATUS)+256*sizeof(NAME_BUFFER)];
    25. UCHAR ret;
    26. NCB ncb;
    27. ADAPTER_STATUS * adapter_status;
    28. NAME_BUFFER * name_buffer;
    29. int lanacount;
    30. memset(&ncb,0,sizeof(NCB));
    31. memset(ncb_buffer,0xa3,sizeof(ADAPTER_STATUS)+256*sizeof(NAME_BUFFER));
    32. adapter_status=(ADAPTER_STATUS *)ncb_buffer;
    33. name_buffer=(NAME_BUFFER *)(ncb_buffer+sizeof(ADAPTER_STATUS));
    34. ncb.ncb_lana_num=0;
    35. ncb.ncb_lsn=0;
    36. ncb.ncb_num=0;
    37. ncb.ncb_command=NCBRESET;
    38. // if(NRC_GOODRET!=(ret=Netbios(&ncb)))
    39. {
    40. // return -2;
    41. }
    42. for(lanacount=0;lanacount<=0;lanacount++)
    43. {
    44. memset(&ncb,0,sizeof(NCB));
    45. memset(ncb_buffer,0xa3,sizeof(ADAPTER_STATUS)+256*sizeof(NAME_BUFFER));
    46. //设置输入
    47. ncb.ncb_command=NCBASTAT;
    48. ncb.ncb_buffer=(unsigned char *)ncb_buffer;
    49. ncb.ncb_length=sizeof(ADAPTER_STATUS)+256*sizeof(NAME_BUFFER);
    50. memset((char *)ncb.ncb_callname,' ',15);
    51. ncb.ncb_callname[15]='\0';
    52. memcpy((char *)ncb.ncb_callname,ip,strlen(ip));
    53. //预先设置输出(无意义)
    54. name_buffer->name[0]='\0';
    55. ncb.ncb_lana_num=(UCHAR)lanacount;
    56. if(NRC_GOODRET==(ret=Netbios(&ncb)))
    57. {
    58. break;
    59. }
    60. else
    61. {
    62. // showret(ret);
    63. }
    64. }
    65. if(0
    66. {
    67. return -3;
    68. }
    69. memcpy(machname,name_buffer[0].name,16);
    70. return 1;
    71. }

            因为取机器名比较困难,所以我同时使用了socket函数和Netbios。具体代码无关紧要了,因为早已经过时,主要目的是看看Netbios接口有多令人震惊。

            Netbios接口如下:

    1. UCHAR Netbios(
    2. PNCB pncb
    3. );

           好简洁啊!真是令人赞叹!

           只有一个参数,是个指针,指向这个:

    1. typedef struct _NCB {
    2. UCHAR ncb_command;
    3. UCHAR ncb_retcode;
    4. UCHAR ncb_lsn;
    5. UCHAR ncb_num;
    6. PUCHAR ncb_buffer;//这是个指针
    7. WORD ncb_length;
    8. UCHAR ncb_callname[NCBNAMSZ];
    9. UCHAR ncb_name[NCBNAMSZ];
    10. UCHAR ncb_rto;
    11. UCHAR ncb_sto;
    12. void()(_NCB *) * ncb_post;//这里又是一个指针
    13. UCHAR ncb_lana_num;
    14. UCHAR ncb_cmd_cplt;
    15. #if ...
    16. UCHAR ncb_reserve[18];
    17. #else
    18. UCHAR ncb_reserve[10];
    19. #endif
    20. HANDLE ncb_event;
    21. } NCB, *PNCB;

            这个结构里面还包括一个指向这种结构的指针,也就是可以无限级联下去。

            第一个成员ncb_command是命令,我大概数了一下,有26种命令,也就是这个结构有26种解释。

            每种命令仅仅使用其它成员的一小部分。其中ncb_buffer指针指向的结构视命令不同而不同。比如某个命令要求ncb_buffer指向这个结构:

    1. typedef struct _SESSION_HEADER {
    2. UCHAR sess_name;
    3. UCHAR num_sess;
    4. UCHAR rcv_dg_outstanding;
    5. UCHAR rcv_any_outstanding;
    6. } SESSION_HEADER, *PSESSION_HEADER;

            类似的结构体有八个。

            虽说按照说明书往下啃是可以理解全部的,但确实有一种啃单片机手册的感觉。

            这个东西被淘汰了,该!

    (这里是结束)

  • 相关阅读:
    python2和python3有什么区别
    智慧路灯杆AI监测应用,让高速出行更安全
    java 文档查看技巧
    使用verdaccio+docker搭建npm私有仓库以及使用
    [Linux打怪升级之路]-yun安装和gcc的使用
    分布式运用之rsync远程同步
    L1&L2,范数&损失
    Python 基于 selenium 实现不同商城的商品价格差异分析系统
    校园表白墙源码修复版
    用友BIP3|YonSuite:世界级的公有云平台,书写中国SaaS产业新篇章
  • 原文地址:https://blog.csdn.net/2301_77171572/article/details/133787335