npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zllling/pangolin

v1.0.1

Published

tcp proxy

Readme

LCX-内网穿透

背景

​ 由于NAT设备的存在,使得外网无法直接访问内网IP,因此需要内网穿透技术,通过一台外网的服务器以及内网的客户端,就可以实现对内网内容的访问。

相关内容

  • 代理

    image-20210415162937277

    ​ 如图所示,对于代理来说,用户位于客户端侧,如果有新的用户,只要向服务端发起新的连接请求,服务端将收到的新的连接与目标之间建立双向的管道即可。客户端也是同理,将用户的sock与新建立的连接建立双向管道。

    // client
      
    userSock.pipe(serverConnection)
    serverConnection.pipe(userSock);
      
      
    // server
      
    clientSock.pipe(targetSock);
    targetSock.pipe(clientSock);

    ​ 这样就完成了最简单的代理功能。

    可以拓展的功能有:

    • 可以在客户端与服务端之间添加认证的机制
    • 可以在客户端与服务端之间加密传输
  • 内网穿透

    image-20210415163527381

    ​ 与代理不同,由于用户位于Server侧,但是建立连接只能由Client主动向Server发起,因为NAT等设备使得Server无法直接连接Client,Server与Client之间的通信只能通过Client主动建立的socket来进行。(是否可以通过socket获取到真实的ip+端口,然后server主动向client建立连接,NAT是将某个IP+端口分配给某一内网主机,有些NAT可能会阻止来自外部主动建立的连接)。

    ​ 因此,用户与目标之间的多路通信必须通过一条由client到server的连接来完成。

难点

  • 传输时需要区分不同用户的数据
  • 当目标socket关闭后,需要通知对应的用户socket也关闭,避免占用过多内存
  • 因为有不同的用户会通过一个连接进行数据传输,因此需要自定义数据包格式

遇到的问题

  • 使用lcx下载大文件出错
    • 这是因为数据包的长度加上自定义的包头之后超出了socket预先设置的缓冲区大小。
    • 解析数据包时需要判断当前收到的buffer长度与解析得到的数据包长度之间的关系,如果数据包长度大于当前buffer,需要将当前buffer缓存,等待下一次收到数据之后再处理。
  • 在进行编码包传输之前,先使用建立的socket进行简单的通信,传输服务端要监听的端口,之后再传输编码过的包,发现无法传输。
    • 这是因为给通信的socket添加了不同的处理函数。
    • 使用自定义的包头来区分不同类型的通信。(简单的定义协议)
  • socket的error事件与close事件重复触发
    • close事件会在error之后触发,因此需要考虑处理函数的重复执行问题,需要增加判断。
    • 但是不可以只监听close事件,因为这样error会抛出导致程序终止。
  • 客户端关闭后,服务端如何解除原来监听端口的占用,使得后续的连接可以使用?
    • 主动释放空间,调用server.close和server.unref
  • 服务端故障之后,客户端定时尝试重新连接
    • 在故障之后,客户端启动定时任务

待完善功能

  • 连接测速功能