Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

minitcp

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

minitcp

  • 0.17.0
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

Minitcp

Presentation

A little tool for doing some TCP/UDP sockets communications.

This tool have no pretention : it is not EventMachine ! :

  • no mainloop,
  • many threads are created/deleted.
  • it is useful for send some data one-shot, test a ascii communication in few minutes...
  • should be equivalent to netcat+bash ...

A TCP client :

MClient.run_one_shot("localhost",2200) do |socket|
   socket.on_any_receive { |data| p "client recieved #{data.inspect}"}
   3.times { |j| socket.puts "Hello  #{j}..." ; sleep(1) }
end.join

An echo server :

srv=MServer.service(2200,"0.0.0.0",22) do |socket|
  socket.on_any_receive { |data|  socket.print(data) }
  socket.on_timer(2000) do
    socket.close
  end
  socket.wait_end
end

A UDP server :

	UDPAgent.on_datagramme("127.0.0.2",SRV_PORT ) { |data,from,p| 
	  puts "Agent: received #{data} from #{from}:#{p}" 
	  data && data.size>3 ? "OK-#{data}." : nil
	}

A UDP sender :

	UDPAgent.on_timer(1000, 
		port: 2232,
		on_timer: proc do
		  data=Time.now.to_i.to_s
		  puts "\n\n\non timer send <#{data}>"
		  {mess: data,host: "127.0.0.2",port: SRV_PORT}
		end,
		on_receive: proc { |data,from,sock| 
		  puts "Client: received #{data} from #{from}"  
		  UDPAgent.send_datagram_on_socket(sock,from.last,from[1],'ack')
		}
	)

A Message agent : Message Client:

MClientAgent.run("localhost",2222) do |chan|
  chan.send_message({date: Time.now.to_f}) 
  chan.on_message do |mess| 
	puts "cli: receive: #{mess.inspect}" 
	chan.close
	nil
  end
  chan.on_timeout(10_000) { p "timeout" ; chan.close rescue nil }
  chan.wait_end
end

Message Server:

MServerAgent.run(2222,"localhost",22) do |chan|
    chan.on_message { |mess|  p mess ; "ok" }
    chan.wait_end
end

Docs: http://rubydoc.info/gems/minitcp

TCP

Client

MClient.run_one_shot(host,port) do |socket| ... end
MClient.run_continious(host,port,time_inter_connection) do |socket| ... end

Client socket is extended with all specifiques commandes (SocketReactive, see Sockets).

Server

srv=MServer.service(port,"0.0.0.0",max_client) do |socket| ... end

Mserver run a GServer. Connected sockets are extended with same module as in client.

Sockets

Handlers are disponibles for any sockets : client or server. All handler's bloc run in distinct thread : so any handler-bloc can wait anything. if socket is closed, handler/thread are cleanly (?) stoped.

  • socket.on_any_receive() {|data| ...} : on receive some data, any size
  • socket.on_n_receive(sizemax=1) {|data| ...} : receives n byte(s) only
  • socket.on_receive_sep(";") {|field | ... } : reveive data until string separator
  • socket.on_timer(value_ms) { ... } : each time do something, if socket is open
  • socket.after(duration) { ... } : do something after n millisecondes, if socket is open

Some primitives are here for help (no thread):

  • received_timeout(sizemax,timeout) : wait for n bytes, with timeout, (blocking caller),
  • wait_end() : wait, (blocking caller) until socket is close. this work only if something has closed the socket.this is possible unicly by receiving 0 bte on a
  • receive_n_bytes / on_receive_sep : bocking version of handler,
  • connected? : test if a close have been done,
  • data_readed() : some receives (receive_sep...) can read more data form sockets, this data are used by n_revieve/any_receive/receive_sep, but they can be read/reseted whith data_readed getseter.

This primitives are declared in SocketReactive module.

UDP

2 type of agents :

  • Server : receive data from anywhere, can reply to sender
  • Timer : emit to everybody, can receive response to them

2 primitives :

  • send_datagram(host,port,message) : create a socket, send mesage and close socket (ca'nt receive a reply)
  • send_datagram_on_socket(socket,host,port,message) : use an existant socket for send a message to ip:port

Messages

Serveur and client MServerAgent and MClientAgent define a 'agent ' which can communicate by messages.

Messages are ruby-data.inspect, max size is 1 MByte.

  • MClientAgent.run(host,port) : connect to a MServerAgent, for communicate by message
  • MServerAgent.run(port,host,max-connections) : message server

in Agent, socket are extended with this capability :

  • socket.send_message(data)
  • socket.on_message { |data| .... ; ret_data} will send ret_data to sender if not nil

See test.rb for an example

TODO

  • Serial line
  • more socket primitive
  • messages Agent : use Marchal instead of inspect/eval ....

Tests case

A TCP proxy, debug tool (see samples/proxy.rb) :

MServer.service(2200,"0.0.0.0",22) do |scli|
  px 2, "======== client Connected ========"
  srv=MClient.run_one_shot("ip",2200) do |ssrv|
     px 1, "======== server Connected ========"
     ssrv.on_any_receive { |data| px 1,data; scli.print data }
     scli.on_any_receive { |data| px 2,data; ssrv.print data}
     ssrv.wait_end
     scli.close rescue nil
  end
  scli.wait_end
  srv.stop rescue nil
end   
def px(sens,data)
  data.each_line {|line| puts "#{(sens==1 ? "> " : "< ")}#{line.chomp}"
end

Test serial protocole-like : header/body => ack/timeout:

  • client send , wait one char acquit or timeout
  • serveur receive heade( size: 4 chars) , then data with size, send ack
   
srv=MServer.service(2200,"0.0.0.0",22) do |socket|
  socket.on_n_receive(4) { |data| 
     size=data.to_i
     data=socket.recv(size)
     puts "  Server recieved buffer : #{data.inspect}"
     if rand(100)>50
        socket.print("o") 
     else 
        puts "  !!!non-ack by serv"
     end
  }
  socket.on_timer(40*1000) { puts " serv close after 40 seconds"; socket.close }
  socket.wait_end
end   

MClient.run_one_shot("localhost",2200) do |socket|
   10.times { |j| 
	   size=rand(1..10)
	   puts "Sending #{size} data..."
	   data='*'*size
	   socket.print "%04d" % size
	   socket.print data 
	   p socket.received_timeout(1,100)  ? "ack ok" : "!!! timeout ack"
   }
   p "end client"
end.join


FAQs

Package last updated on 18 May 2016

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc