Coder Social home page Coder Social logo

shadowsocks / shadowsocks-go Goto Github PK

View Code? Open in Web Editor NEW
6.6K 6.6K 3.3K 405 KB

go port of shadowsocks (Deprecated)

Home Page: http://shadowsocks.github.io/shadowsocks-go

License: Apache License 2.0

Makefile 0.79% Go 88.09% Shell 11.01% Batchfile 0.11%

shadowsocks-go's Introduction

Deprecated

Use https://github.com/shadowsocks/go-shadowsocks2 instead.

shadowsocks-go

Current version: 1.2.2 Build Status

shadowsocks-go is a lightweight tunnel proxy which can help you get through firewalls. It is a port of shadowsocks.

The protocol is compatible with the origin shadowsocks (if both have been upgraded to the latest version).

Note server_password option syntax changed in 0.6.2, the client now connects to servers in the order specified in the config.

Please develop on the latest develop branch if you want to send pull request.

Install

Download precompiled binarys from the release page. (All compiled with cgo disabled, except the mac version.)

You can also install from source (assume you have go installed):

# on server
go get github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-server
# on client
go get github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-local

It's recommended to disable cgo when compiling shadowsocks-go. This will prevent the go runtime from creating too many threads for dns lookup.

Usage

Both the server and client program will look for config.json in the current directory. You can use -c option to specify another configuration file.

Configuration file is in json format and has the same syntax with shadowsocks-nodejs. You can download the sample config.json, change the following values:

server          your server ip or hostname
server_port     server port
local_port      local socks5 proxy port
method          encryption method, null by default (table), the following methods are supported:
                    aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb, cast5-cfb, des-cfb, rc4-md5, rc4-md5-6, chacha20, salsa20, rc4, table
password        a password used to encrypt transfer
timeout         server option, in seconds

Run shadowsocks-server on your server. To run it in the background, run shadowsocks-server > log &.

On client, run shadowsocks-local. Change proxy settings of your browser to

SOCKS5 127.0.0.1:local_port

About encryption methods

AES is recommended for shadowsocks-go. Intel AES Instruction Set will be used if available and can make encryption/decryption very fast. To be more specific, aes-128-cfb is recommended as it is faster and secure enough.

rc4 and table encryption methods are deprecated because they are not secure.

One Time Auth

OTA function is deprecated because it is reported to have potential security risk.

Command line options

Command line options can override settings from configuration files. Use -h option to see all available options.

shadowsocks-local -s server_address -p server_port -k password
    -m aes-128-cfb -c config.json
    -b local_address -l local_port
shadowsocks-server -p server_port -k password
    -m aes-128-cfb -c config.json
    -t timeout

Use -d option to enable debug message.

Use multiple servers on client

server_password    specify multiple server and password, server should be in the form of host:port

Here's a sample configuration client-multi-server.json. Given server_password, client program will ignore server_port, server and password options.

Servers are chosen in the order specified in the config. If a server can't be connected (connection failure), the client will try the next one. (Client will retry failed server with some probability to discover server recovery.)

Multiple users with different passwords on server

The server can support users with different passwords. Each user will be served by a unique port. Use the following options on the server for such setup:

port_password   specify multiple ports and passwords to support multiple users

Here's a sample configuration server-multi-port.json. Given port_password, server program will ignore server_port and password options.

Update port password for a running server

Edit the config file used to start the server, then send SIGHUP to the server process.

Note to OpenVZ users

Use OpenVZ VM that supports vswap. Otherwise, the OS will incorrectly account much more memory than actually used. shadowsocks-go on OpenVZ VM with vswap takes about 3MB memory after startup. (Refer to this issue for more details.)

If vswap is not an option and memory usage is a problem for you, try shadowsocks-libev.

shadowsocks-go's People

Contributors

abeluck avatar amyangfei avatar arthurkiller avatar ayanamist avatar clowwindy avatar codelingobot avatar cyfdecyf avatar ddatsh avatar defia avatar defp avatar dujiulun avatar genzj avatar gyteng avatar haraldnordgren avatar hugozhu avatar jackyyf avatar lins05 avatar lixin9311 avatar liyiheng avatar lxohi avatar lzjluzijie avatar madeye avatar muzea avatar ssoxer avatar terwey avatar thomasf avatar ushuz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shadowsocks-go's Issues

Shadowsocks not compatible with PAC files

It seems that PAC files redirection to SOCKS, coded as SOCKS 127.0.0.1:1383 for instance, are not compatible with Shadowsocks.
Shadowsocks throws a socks handshake: socks version not supported error, likely coming from local.go, meaning the browser call to the shadowsocks-local is indeed not using the SOCKS5 protocol.
So is it a Shadowsocks misinterpretation or is it a problem with PAC support from browsers (which indeed for the majority support SOCKS5).

In worst case, any recommendation to build a site whitelist/blacklist in combination with shadowsocks?

为什么启动后只能监听ipv6端口呢

本来还正常的,然后修改了下 hostname 。。。。就不正常了。。启动的服务器只能lsof 命令查看只能监听ipv6端口。。。

之前是有ipv6和v4的。。。

不知道怎么解决呢。。。

谢谢~

File descriptor leak.

After like running for a day, shadowsocks-go spits:
accept: accept tcp [::]:8080: too many open files
repeatedly and refuse to work.
"ls /proc/[pid]/fd" revealed about 1000 fds.

客户端一直报must specify server address, password and both server/local port

win7,我的config.js在路径exe同一个目录,放在%gopath%/bin/目录下,

{
  "configs": [
    {
      "local_port": "1080",
      "server_password": [
        ["xxxx:1111", "yyyy"],
        ["yyyyyy:1222", "xxxxx"]
      ],
      "method": "aes-256-cfb",
      "timeout": "600",
      "local_address": "0.0.0.0"
    }
  ]
}

按理说,只要有server_password在,就不该抛那个错误啊,百思不得其解。
另外,即使我跑shadowsocks-local.exe -d true也没有多余的log打出来,一直是那句must specify server address, password and both server/local port

谢谢

随机取连接和处理信号的建议

假如有多个后端,用server_password: [...]配多个,但是观察到实际上只会取第一个后端来连接。

看了一下local.gocreateServerConn方法,的确是从0开始取的,我建议改成,随机从多个后端取一个,随机分布要尽可能均匀一些,努力让多个后端平均的承担流量。

还是这个,从rand.Intn!=0看有点坏连接优先的选择,不用管坏了,这个地方改为随机取,只要通就返回,不通取随机下一个,最多随机n遍。
我对go不了解,胡乱改了个简单的:

func createServerConn(rawaddr []byte, addr string) (remote *ss.Conn, err error) {
    n := len(servers.srvCipher)
    for i := 0; i < n; i++ {
        j := rand.Intn(n<<2) >> 2
        remote, err = connectToServer(j, rawaddr, addr)
        if err == nil {
            return
        }
    }
    return nil, err
}

其实选连接这个地方,可以搞复杂的,在PipeThenClose里面做一些简单计算,给后端连接评价权重,用权重优先选连接,或者用最少连接数优先等等。

还有,最好能在local.go中注册一下信号处理,对sigint,sigterm等中止信号后,把所有活动的Connection全部关闭,然后退出,总之还是正常关闭连接好些,否则服务器那端会看到peer reset之类的错误。

另外,在pipe.go这个地方的缓冲区大小,设置成n倍的MSS大小可能会更快的读写到响应,对于ADSL用户MTU一般是1492 所以tcp的MSS就是1452,建议设置为1452的n倍,可能会更好,当然我没有大量测试,只是一个想法。

感谢你的作品。

Shadowsocks server stops working randomly

It happens very rarely (once every few months, with ~10 active clients), but sometimes all clients suddenly stop being able to get traffic.
It's still running on the server but it's not serving request anymore.

A restart of the process solves the problem instantly.

Does anyone have the same problem? What additional test could I run when it happens to understand where the problem comes from?

I have it installed on Ubuntu.

PS: I put it on the go version since it's the version I use but might well be a general Shadowsocks problem.

error getting request <...> addr type <xx> not supported

I can establish a connection between server and local, but I can't get traffic go through:

server side:
shadowsocks-server -d > log & tail -f log 2014/03/13 19:25:54 server listening port 8388 ... 2014/03/13 19:26:18 creating cipher for port: 8388 [DEBUG] 19:26:18 new client <client_ip>:13011-><server_ip>:8388 2014/03/13 19:26:18 error getting request <client_ip>:13011 <server_ip>:8388 addr type 94 not supported [DEBUG] 19:26:18 closed pipe <client_ip>:13011<-> [DEBUG] 19:26:19 new client <client_ip>:13036-><server_ip>:8388 2014/03/13 19:26:19 error getting request <client_ip>:13036 <server_ip>:8388 addr type 156 not supported [DEBUG] 19:26:19 closed pipe <client_ip>:13036<-> [DEBUG] 19:26:19 new client <client_ip>:13045-><server_ip>:8388 2014/03/13 19:26:19 error getting request <client_ip>:13045 <server_ip>:8388 addr type 10 not supported [DEBUG] 19:26:19 closed pipe <client_ip>:13045<-> [DEBUG] 19:26:20 new client <client_ip>:13085-><server_ip>:8388 2014/03/13 19:26:20 error getting request <client_ip>:13085 <server_ip>:8388 addr type 14 not supported [DEBUG] 19:26:20 closed pipe <client_ip>:13085<-> [DEBUG] 19:27:06 new client <client_ip>:14970-><server_ip>:8388 2014/03/13 19:27:06 error getting request <client_ip>:14970 <server_ip>:8388 addr type 36 not supported [DEBUG] 19:27:06 closed pipe <client_ip>:14970<-> [DEBUG] 19:27:06 new client <client_ip>:14973-><server_ip>:8388 2014/03/13 19:27:06 error getting request <client_ip>:14973 <server_ip>:8388 addr type 64 not supported [DEBUG] 19:27:06 closed pipe <client_ip>:14973<-> [DEBUG] 19:27:06 new client <client_ip>:14986-><server_ip>:8388 2014/03/13 19:27:06 error getting request <client_ip>:14986 <server_ip>:8388 addr type 119 not supported [DEBUG] 19:27:06 closed pipe <client_ip>:14986<-> [DEBUG] 19:27:06 new client <client_ip>:14987-><server_ip>:8388 2014/03/13 19:27:06 error getting request <client_ip>:14987 <server_ip>:8388 addr type 249 not supported [DEBUG] 19:27:06 closed pipe <client_ip>:14987<-> [DEBUG] 19:27:06 new client <client_ip>:14989-><server_ip>:8388 2014/03/13 19:27:06 error getting request <client_ip>:14989 <server_ip>:8388 addr type 30 not supported [DEBUG] 19:27:06 closed pipe <client_ip>:14989<-> [DEBUG] 19:27:06 new client <client_ip>:14990-><server_ip>:8388 2014/03/13 19:27:06 error getting request <client_ip>:14990 <server_ip>:8388 addr type 154 not supported [DEBUG] 19:27:06 closed pipe <client_ip>:14990<-> [DEBUG] 19:27:07 new client <client_ip>:14996-><server_ip>:8388 2014/03/13 19:27:07 error getting request <client_ip>:14996 <server_ip>:8388 addr type 42 not supported [DEBUG] 19:27:07 closed pipe <client_ip>:14996<-> [DEBUG] 19:27:07 new client <client_ip>:14998-><server_ip>:8388 2014/03/13 19:27:07 error getting request <client_ip>:14998 <server_ip>:8388 addr type 70 not supported [DEBUG] 19:27:07 closed pipe <client_ip>:14998<-> [DEBUG] 19:27:07 new client <client_ip>:15000-><server_ip>:8388 2014/03/13 19:27:07 error getting request <client_ip>:15000 <server_ip>:8388 addr type 56 not supported [DEBUG] 19:27:07 closed pipe <client_ip>:15000<-> [DEBUG] 19:27:07 new client <client_ip>:15009-><server_ip>:8388 2014/03/13 19:27:07 error getting request <client_ip>:15009 <server_ip>:8388 addr type 136 not supported [DEBUG] 19:27:07 closed pipe <client_ip>:15009<-> [DEBUG] 19:27:07 new client <client_ip>:15021-><server_ip>:8388 2014/03/13 19:27:07 error getting request <client_ip>:15021 <server_ip>:8388 addr type 17 not supported [DEBUG] 19:27:07 closed pipe <client_ip>:15021<-> [DEBUG] 19:27:08 new client <client_ip>:15035-><server_ip>:8388 2014/03/13 19:27:08 error getting request <client_ip>:15035 <server_ip>:8388 addr type 84 not supported [DEBUG] 19:27:08 closed pipe <client_ip>:15035<->

Client side:
shadowsocks-local -d -c .shadowsock 2014/03/13 19:26:12 available remote server <server_ip>:8388 2014/03/13 19:26:12 starting local socks5 server at :2000 ... [DEBUG] 19:26:17 socks connect from 127.0.0.1:56990 [DEBUG] 19:26:18 connected to www.google.com:80 via <server_ip>:8388 [DEBUG] 19:26:18 closed connection to www.google.com:80 [DEBUG] 19:26:18 socks connect from 127.0.0.1:56992 [DEBUG] 19:26:18 connected to www.qwant.com:443 via <server_ip>:8388 [DEBUG] 19:26:19 closed connection to www.qwant.com:443 [DEBUG] 19:26:19 socks connect from 127.0.0.1:56994 [DEBUG] 19:26:19 connected to www.qwant.com:443 via <server_ip>:8388 [DEBUG] 19:26:19 closed connection to www.qwant.com:443 [DEBUG] 19:26:19 socks connect from 127.0.0.1:56996 [DEBUG] 19:26:20 connected to www.qwant.com:443 via <server_ip>:8388 [DEBUG] 19:26:20 closed connection to www.qwant.com:443 [DEBUG] 19:27:05 socks connect from 127.0.0.1:57000 [DEBUG] 19:27:05 socks connect from 127.0.0.1:57002 [DEBUG] 19:27:06 socks connect from 127.0.0.1:57004 [DEBUG] 19:27:06 connected to clients1.google.com:443 via <server_ip>:8388 [DEBUG] 19:27:06 closed connection to clients1.google.com:443 [DEBUG] 19:27:06 socks connect from 127.0.0.1:57006 [DEBUG] 19:27:06 connected to clients1.google.com:443 via <server_ip>:8388 [DEBUG] 19:27:06 closed connection to clients1.google.com:443 [DEBUG] 19:27:06 socks connect from 127.0.0.1:57008 [DEBUG] 19:27:06 socks connect from 127.0.0.1:57010 [DEBUG] 19:27:06 connected to clients1.google.com:443 via <server_ip>:8388 [DEBUG] 19:27:06 closed connection to clients1.google.com:443 [DEBUG] 19:27:06 connected to www.ipchicken.com:80 via <server_ip>:8388 [DEBUG] 19:27:06 socks connect from 127.0.0.1:57012 [DEBUG] 19:27:06 connected to clients1.google.com:443 via <server_ip>:8388 [DEBUG] 19:27:06 closed connection to clients1.google.com:443 [DEBUG] 19:27:06 connected to clients1.google.com:443 via <server_ip>:8388 [DEBUG] 19:27:06 closed connection to clients1.google.com:443 [DEBUG] 19:27:06 socks connect from 127.0.0.1:57014 [DEBUG] 19:27:06 closed connection to www.ipchicken.com:80 [DEBUG] 19:27:06 connected to clients1.google.com:443 via <server_ip>:8388 [DEBUG] 19:27:06 closed connection to clients1.google.com:443 [DEBUG] 19:27:06 socks connect from 127.0.0.1:57016 [DEBUG] 19:27:06 connected to clients1.google.com:443 via <server_ip>:8388 [DEBUG] 19:27:06 closed connection to clients1.google.com:443 [DEBUG] 19:27:07 socks connect from 127.0.0.1:57018 [DEBUG] 19:27:07 connected to clients1.google.com:443 via <server_ip>:8388 [DEBUG] 19:27:07 connected to www.google.com:80 via <server_ip>:8388 [DEBUG] 19:27:07 closed connection to clients1.google.com:443 [DEBUG] 19:27:07 socks connect from 127.0.0.1:57020 [DEBUG] 19:27:07 closed connection to www.google.com:80 [DEBUG] 19:27:07 connected to clients1.google.com:443 via <server_ip>:8388 [DEBUG] 19:27:07 closed connection to clients1.google.com:443 [DEBUG] 19:27:07 socks connect from 127.0.0.1:57022 [DEBUG] 19:27:08 connected to www.google.com:80 via <server_ip>:8388 [DEBUG] 19:27:08 closed connection to www.google.com:80

Password bug

It's on windows client.
When password include %
cli client can't pass authentication,other client not have that problem.

rc4-md5加密错误

error getting request 58.19.126.63:48548 107.182.181.76:8388 addr type 213 not supported

这是我在服务器端得到的错误类型,在没有改变任何其他配置仅改变加密方式后,不再出现问题了。

install error

the cmd
go get github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-server
yields the following error:
/usr/lib/go/src/pkg/github.com/shadowsocks/shadowsocks-go/shadowsocks/encrypt.go:205: function ends without a return statement

Without prior knowledge of go language, the source code seems ok to me.

I installed latest golang package on Ubuntu 12.04.
go version returns go version go1

Specify server bind interface

It seems shadowsocks-server binds to all interfaces (0.0.0.0).

{
    "server":"123.123.123.123",
    "server_port":17777,
}

But:

root@MyMachine:~# lsof -i :17777
COMMAND     PID  USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME
shadowsoc 10333 me    3u  IPv4 3665407420      0t0  TCP *:17777 (LISTEN)

I expected this:

TCP 123.123.123.123:17777 (LISTEN)

Is there a config setting for the server-side bind IP? If not, maybe I can add it and send a pull request. Do you have a suggested implementation?

可不可以将二进制文件放到release页面中?

想对shadowsocks-go进行二次封装,想在自动构建脚本中下载二进制文件(还有使用Travis-CI自动构建)

所以希望能够将shadowsocks-go的二进制文件发布到release页面。

比如可以用shadowsocks-go-{type}-{platform}-{version}.zip来匹配二进制包。

  • _type_可以取localserver
  • _platform_可以取mac64linux32linux64win32win64
  • _version_建议用v1.0.0来标注。

建议local版二进制文件统一为shadowsocks-local ,server版二进制统一为shadowsocks-server,以免脚本调用时需要判断版本。

其实我想的是,在项目的配置文件中写好依赖,比如0.1.1,脚本自动下载,打包应用。

Client bind interface

local_address in config.json is ignored, as is the command line option -b="" (for bind I guess).

Server incompilable.

Go version go1.0.2

Debian 7

$ sudo go get github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-server
# github.com/shadowsocks/shadowsocks-go/shadowsocks
/usr/lib/go/src/pkg/github.com/shadowsocks/shadowsocks-go/shadowsocks/encrypt.go:205: function ends without a return statement

长时间运行之后会 hang

时间长了时候客户端这边的请求就没回应了,不知道是怎么回事,重启就好了。

有什么头绪没?或者怎么来 debug?

Shadowsocks statistics

Hey there
I'm using shadowsocks-go in multiuser setup. (I think I got some abuser.)
I want to obtain some data from shadowsocks.

  • Which server/port each user access and when.
  • Byte count that each user used. (I think this can be done with iptables by specify port number but I don't want to count bytes that alleged sent by someone else without user's password to user's assigned port.) In another phrase: I want to count bytes usage both upload and download combined or separated but just count only when someone who have the password perform the action.

Can you add this ability to shadowsocks-go?
If not could you guide me where can I add my own hook function to do the jobs?

OpenVZ VPS上内存占用过多

在内存为128M、系统为64bit Debian6的OpenVZ VPS上只能保持25个左右的连接,每个连接使用了3个goroutine,算下来每个goroutine占用了1MB+的内存。

连接大于25个时,不能开辟新的内存空间,程序崩溃。

add waiting method for test.sh

Sleeping is not a solid way to wait util client and server start. Suggest the following method:

while ! nc -z -w 4 127.0.0.1 $LOCAL_PORT; do
    sleep 0.1
done
while ! nc -z -w 4 127.0.0.1 8389; do
    sleep 0.1
done

Have been tested.

go get 时报错

错误信息如下:

/Users/MiincGu/Develop/GOPATH/src/github.com/shadowsocks/shadowsocks-go/shadowsocks/encrypt.go:5:2: code in directory /Users/MiincGu/Develop/GOPATH/src/github.com/golang/crypto/blowfish expects import "golang.org/x/crypto/blowfish"
/Users/MiincGu/Develop/GOPATH/src/github.com/shadowsocks/shadowsocks-go/shadowsocks/encrypt.go:6:2: code in directory /Users/MiincGu/Develop/GOPATH/src/github.com/golang/crypto/cast5 expects import "golang.org/x/crypto/cast5"

加入 -u 参数时,错误信息如下:

package github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-server
    imports github.com/golang/crypto/blowfish
    imports github.com/golang/crypto/blowfish
    imports github.com/golang/crypto/blowfish: code in directory /Users/MiincGu/Develop/GOPATH/src/github.com/golang/crypto/blowfish expects import "golang.org/x/crypto/blowfish"
package github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-server
    imports github.com/golang/crypto/blowfish
    imports github.com/golang/crypto/cast5
    imports github.com/golang/crypto/cast5
    imports github.com/golang/crypto/cast5: code in directory /Users/MiincGu/Develop/GOPATH/src/github.com/golang/crypto/cast5 expects import "golang.org/x/crypto/cast5"

启动后占用内存还是太大

抱歉,我确实看到了之前反映内存占用大的issue,
编译Go的时候我没来得及禁用CGO,一启动ShadowSocks-server,在top里面看到用去790+MB的内存。

OS: NetBSD 6.0.1
GO: 1.1pre
shadowsocks-go:0.6

或许代码上还有改善的余地?(控制线程数?即使销毁无用进程)

write function doesn't use correctly

hi,
After i have read the code , i think there may be exists a bug becasue write function does't use correctly.
In the pipe.go line 38 . As we know, the length write function return which it's truely have been wirtten to the stream.
if _, err = dst.Write(buf[0:n]); err != nil {
Debug.Println("write:", err)
break
}

but this code doesn't use it . We can slove this problem use a loop

        var sum, write = 0, 0
        for sum < n {
            write, err = dst.Write(buf[sum:n])
            sum += write
            if err != nil {
                Debug.Println("write:", err)
                break
            }
        }

i hope it's useful
thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.