Skip to content

Commit 91cb90e

Browse files
committed
Adding examples in documentation
1 parent a17fa00 commit 91cb90e

7 files changed

Lines changed: 248 additions & 55 deletions

File tree

README.md

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# RawSocketPy
22

3+
[API Documentation](https://rawsocket-python.readthedocs.io/en/latest/api.html)
4+
35
Raw socket is a layer 2 python library for communication using the MAC addresses only.
46

57
This allows you to create a custom made Ethernet/WiFi communication system which is **not** using IP nor TCP/UDP or to debug custom frames such as SERCOS III, Profibus, ARP, PTP, ...
@@ -91,29 +93,87 @@ sock.send("other data", ethertype="\xEE\xFF") # Broadcast "other data" with an e
9193
On another machine, you can run the following:
9294

9395
```python
94-
from rawsocketpy import RawSocket, u_to_str
96+
from rawsocketpy import RawSocket, to_str
9597

9698
sock = RawSocket("wlp2s0", 0xEEFA)
9799
packet = sock.recv()
98100
# The type of packet is RawPacket() which allows pretty printing and unmarshal the raw data.
99101

102+
# If you are using Python2, all data is encoded as unicode strings "\x01.." while Python3 uses bytearray.
103+
100104
print(packet) # Pretty print
101-
packet.dest # unicode string "\xFF\xFF\xFF\xFF\xFF\xFF"
102-
packet.src # unicode string "\x12\x12\x12\x12\x12\x13"
103-
packet.type # unicode string "\xEE\xFA"
104-
packegt.data # unicode string "some data"
105+
packet.dest # string "\xFF\xFF\xFF\xFF\xFF\xFF" or bytearray(b"\xFF\xFF\xFF\xFF\xFF\xFF")
106+
packet.src # string "\x12\x12\x12\x12\x12\x13" or bytearray(b"\x12\x12\x12\x12\x12\x13")
107+
packet.type # string "\xEE\xFA" or bytearray([b"\xEE\xFA"]
108+
packegt.data # string "some data" or bytearray(b"some data"]
109+
110+
print(to_str(packet.dest)) # Human readable MAC: FF:FF:FF:FF:FF:FF
111+
print(to_str(packet.type, "")) # Human readable type: EEFA
112+
```
113+
114+
## Stateless blocking Server
115+
116+
```python
117+
from rawsocketpy import RawServer
118+
119+
class LongTaskTest(RawRequestHandler):
120+
def handle(self):
121+
time.sleep(1)
122+
print(self.packet)
123+
124+
def finish(self):
125+
print("End")
126+
127+
def setup(self):
128+
print("Begin")
129+
130+
def main():
131+
rs = RawServer("wlp2s0", 0xEEFA, LongTaskTest)
132+
rs.spin()
133+
134+
if __name__ == '__main__':
135+
main()
136+
```
137+
138+
## Stateful Asynchronous server
139+
140+
Available **only** if **gevent** is installed.
141+
142+
```python
143+
from rawsocketpy import RawRequestHandler, RawAsyncServerCallback
144+
import time
145+
146+
def callback(handler, server):
147+
print("callback")
148+
handler.setup()
149+
handler.handle()
150+
handler.finish()
151+
152+
153+
class LongTaskTest(RawRequestHandler):
154+
def handle(self):
155+
time.sleep(1)
156+
print(self.packet)
157+
158+
def finish(self):
159+
print("End")
160+
161+
def setup(self):
162+
print("Begin")
163+
164+
def main():
165+
rs = RawAsyncServerCallback("wlp2s0", 0xEEFA, LongTaskTest, callback)
166+
rs.spin()
105167

106-
print u_to_str(packet.dest) # Human readable MAC: FF:FF:FF:FF:FF:FF
107-
print u_to_str(packet.type, "") # Human readable type: EEFA
168+
if __name__ == '__main__':
169+
main()
108170
```
109171

110172
## I want to contribue!!
111173

112174
You are free to contribue, the following capabilities are welcome:
113175

114176
- Windows compatibility
115-
- Async implementation (callbacks on new data)
116-
- Readthedocs documentation
117177
- More Python versions and OS tests
118178

119179
## Credits

docs/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Documentation
2+
3+
Build: `make html`

docs/async.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
Go asynchronous
2+
===============================================
3+
4+
Install gevent and you are ready to use asynchronous servers. The asynchronous server is a very small modification from the base :class:`RawServer`.
5+
6+
.. code-block:: bash
7+
:caption: Gevent installation command
8+
:name: Gevent installation command
9+
10+
sudo pip -H install gevent
11+
12+
13+
**Stateless** **Asynchronous** server:
14+
15+
.. code-block:: python
16+
:caption: Stateless Asynchronous server
17+
:name: Stateless Asynchronous server
18+
19+
from rawsocketpy import RawRequestHandler, RawAsyncServer
20+
import time
21+
22+
class LongTaskTest(RawRequestHandler):
23+
def handle(self):
24+
time.sleep(1)
25+
print(self.packet)
26+
27+
def finish(self):
28+
print("End")
29+
30+
def setup(self):
31+
print("Begin")
32+
33+
def main():
34+
rs = RawAsyncServer("wlp2s0", 0xEEFA, LongTaskTest)
35+
rs.spin()
36+
37+
if __name__ == '__main__':
38+
main()
39+
40+
**Statefull** **Asynchronous** server:
41+
42+
.. code-block:: python
43+
:caption: Statefull Asynchronous server
44+
:name: Statefull Asynchronous server
45+
46+
from rawsocketpy import RawRequestHandler, RawAsyncServerCallback
47+
import time
48+
49+
def callback(handler, server):
50+
print("Testing")
51+
handler.setup()
52+
handler.handle()
53+
handler.finish()
54+
55+
class LongTaskTest(RawRequestHandler):
56+
def handle(self):
57+
time.sleep(1)
58+
print(self.packet)
59+
60+
def finish(self):
61+
print("End")
62+
63+
def setup(self):
64+
print("Begin")
65+
66+
def main():
67+
rs = RawAsyncServerCallback("wlp2s0", 0xEEFA, LongTaskTest, callback)
68+
rs.spin()
69+
70+
if __name__ == '__main__':
71+
main()
72+

docs/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ Welcome to RawSocketPy's documentation!
99
quicktest
1010
api
1111
raw_socket
12-
server_mode
12+
server
13+
async
1314

1415
Indices and tables
1516
==================

docs/raw_socket.rst

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,45 @@
1-
Raw sockets
2-
============
1+
Low level socket
2+
================
33

4-
The raw sockets is the base of the library.
4+
You can use the library with a low level socket, where you handle to send and receive.
55

6+
.. code-block:: python
7+
:caption: Sending data
8+
:name: Sending data
69
10+
from rawsocketpy import RawSocket
711
12+
# 0xEEFA is the ethertype
13+
# The most common are available here: https://en.wikipedia.org/wiki/EtherType
14+
# The full official list is available here: https://regauth.standards.ieee.org/standards-ra-web/pub/view.html#registries
15+
# Direct link: https://standards.ieee.org/develop/regauth/ethertype/eth.csv
16+
# You can use whatever you want but using a already use type can have unexpected behaviour.
17+
sock = RawSocket("wlp2s0", 0xEEFA)
18+
19+
sock.send("some data") # Broadcast "some data" with an ethertype of 0xEEFA
20+
21+
sock.send("personal data", dest="\xAA\xBB\xCC\xDD\xEE\xFF") # Send "personal data to \xAA\xBB\xCC\xDD\xEE\xFF with an ether type of 0xEEFA
22+
23+
sock.send("other data", ethertype="\xEE\xFF") # Broadcast "other data" with an ether type of 0xEEFF
24+
25+
26+
.. code-block:: python
27+
:caption: Receiving data
28+
:name: Receiving data
29+
30+
from rawsocketpy import RawSocket, to_str
31+
32+
sock = RawSocket("wlp2s0", 0xEEFA)
33+
packet = sock.recv()
34+
# The type of packet is RawPacket() which allows pretty printing and unmarshal the raw data.
35+
36+
# If you are using Python2, all data is encoded as unicode strings "\x01.." while Python3 uses bytearray.
37+
38+
print(packet) # Pretty print
39+
packet.dest # string "\xFF\xFF\xFF\xFF\xFF\xFF" or bytearray(b"\xFF\xFF\xFF\xFF\xFF\xFF")
40+
packet.src # string "\x12\x12\x12\x12\x12\x13" or bytearray(b"\x12\x12\x12\x12\x12\x13")
41+
packet.type # string "\xEE\xFA" or bytearray([b"\xEE\xFA"]
42+
packegt.data # string "some data" or bytearray(b"some data"]
43+
44+
print(to_str(packet.dest)) # Human readable MAC: FF:FF:FF:FF:FF:FF
45+
print(to_str(packet.type, "")) # Human readable type: EEFA

docs/server.rst

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
Make it a server
2+
================
3+
4+
Stateless blocking server example: Each time you receive a packet, it will be of type ``LongTaskTest`` and run ``setup()``, ``handle()`` and finally ``finish``.
5+
If the handle/setup fails, the ``finish`` function will be executed.
6+
7+
.. code-block:: python
8+
:caption: Sending data
9+
:name: Sending data
10+
11+
from rawsocketpy import RawServer, RawRequestHandler
12+
13+
class LongTaskTest(RawRequestHandler):
14+
def setup(self):
15+
print("Begin")
16+
17+
def handle(self):
18+
time.sleep(1)
19+
print(self.packet)
20+
21+
def finish(self):
22+
print("End")
23+
24+
def main():
25+
rs = RawServer("wlp2s0", 0xEEFA, LongTaskTest)
26+
rs.spin()
27+
28+
if __name__ == '__main__':
29+
main()
30+
31+
**Statefull** and **blocking** server using a centralised callback. It does guarantee that the callback is called in ethernet packet order, but if the execution is long, you will loose packets.
32+
33+
.. code-block:: python
34+
:caption: Sending data
35+
:name: Sending data
36+
37+
from rawsocketpy import RawServerCallback, RawRequestHandler
38+
39+
def callback(handler, server):
40+
print("Testing")
41+
handler.setup()
42+
handler.handle()
43+
handler.finish()
44+
45+
class LongTaskTest(RawRequestHandler):
46+
def handle(self):
47+
time.sleep(1)
48+
print(self.packet)
49+
50+
def finish(self):
51+
print("End")
52+
53+
def setup(self):
54+
print("Begin")
55+
56+
def main():
57+
rs = RawServerCallback("wlp2s0", 0xEEFA, LongTaskTest, callback)
58+
rs.spin()
59+
60+
if __name__ == '__main__':
61+
main()

docs/server_mode.rst

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)