Skip to content

Instantly share code, notes, and snippets.

@xjdrew
Last active December 21, 2015 13:49
Show Gist options
  • Save xjdrew/6315754 to your computer and use it in GitHub Desktop.
Save xjdrew/6315754 to your computer and use it in GitHub Desktop.
ping -> pong server 效率: 单连接: python 2.1W每秒 erlang 4.6W每秒 redis 2.7W每秒 多连接(100)个: python 3W每秒 erlang 11W 每秒 redis 13W每秒 CPU: Intel i5-2400 CPU@3.1GHz
#!/usr/bin/python
# -*- coding: utf-8 -*-
import gevent
from gevent import monkey;monkey.patch_all()
import sys, argparse, socket, time
def ping(sock, requests):
fileobj = sock.makefile()
for i in xrange(requests):
sock.sendall("PING\r\n")
line = fileobj.readline()
if line.strip() != "+PONG":
sys.exit(1)
def run(args):
addr = (args.host, args.port)
clients = args.clients
requests = args.requests
clock = time.clock()
for i in range(args.clients):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(addr)
except socket.error, e:
print("cannot not setup connection to %s:%d" % (addr))
sys.exit(1)
gevent.spawn(ping, sock, requests)
gevent.wait()
diff = time.clock() - clock
print("%d requests per second" % int((clients * requests)/diff))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-s', dest='host',
default='127.0.0.1', help = 'Server hostname (default 127.0.0.1)')
parser.add_argument('-p', dest='port',
default='6666', help = 'Server port (defalut 6666)', type=int)
parser.add_argument('-c', dest='clients',
default=50, help='Number of parallel connections (Default 50)', type=int)
parser.add_argument('-n', dest='requests',
default=10000, help='number of requests per connection (default 10000)', type=int)
args = parser.parse_args()
run(args)
if __name__ == "__main__":
main()
-module(ping).
-export([start/0]).
%% backlog, accept时的缓存队列长度
%% keepalive, 强制回收close_wait状态连接, 避免半连接
%%
start()->
{ok, Listen} = gen_tcp:listen(6666, [binary, {packet,line}, {active,true}]),
spawn(fun()-> seq_loop(Listen) end).
seq_loop(Listen) ->
case gen_tcp:accept(Listen) of
{ok, Socket} ->
spawn(fun() -> seq_loop(Listen) end),
io:format("Socket ~p created~n", [Socket]),
loop(Socket);
{error, Reason} ->
io:format("accept failed:~p~n",[Reason])
end.
loop(Socket) ->
receive
{tcp, Socket, <<"PING\r\n">>} ->
gen_tcp:send(Socket, <<"+PONG\r\n">>),
%spawn(fun() ->worker(Socket) end),
loop(Socket);
{tcp_error, Socket, Reason} ->
io:format("Socket ~p:~p~n",[Socket, Reason]);
{tcp_closed, Socket} ->
io:format("Socket ~p closed~n", [Socket]),
ok
end.
worker(Socket) ->
case gen_tcp:send(Socket, <<"+PONG\r\n">>) of
{error, Reason} ->
io:format("send failed:~p~n",[Reason]);
_ ->
ok
end.
#!/usr/bin/python
import gevent
from gevent.server import StreamServer
def echo(socket):
fileobj = socket.makefile()
while True:
line = fileobj.readline()
if not line:
print("client disconnected")
break
if line.strip() == "PING":
fileobj.write("+PONG\r\n")
fileobj.flush()
def new_connection(socket, address):
gevent.spawn(echo, socket)
if __name__ == "__main__":
server = StreamServer(("0.0.0.0", 6666), new_connection)
server.start()
print("Listen on port: %d" % 6666)
gevent.wait()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment