Twisted python - socket to bind to path on the filesystem - python

I am trying to implement a socket server that receives rsyslog messages from windows or linux os. Ryslog uses omuxsock to output logs to socket server. I want to use twisted python to implement this socket that receives windows event/linux syslog messages. All the examples i've come across documentation only shows how to bind to IP and port. I want twisted socket to bind to a socket file not ip or port. eg., file "/var/syslog.sock"
in python without using twisted this can be done using:
s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
s.bind("/var/syslog.sock")
has anyone implemented socket in twisted python using socket file?

With a reactor that supports IReactorUNIX you can do this either with the lower-level listenUNIX or the higher level UNIXServerEndpoint.
For example
from twisted.internet import reactor
from twisted.internet.endpoints import UNIXServerEndpoint
from twisted.internet.protocols import Factory, Protocol
e = UNIXServerEndpoint(reactor, "/var/syslog.sock")
d = e.listen(Factory.forProtocol(Protocol))
reactor.run()

Related

How can i share a serialport between 2 different processes in Python

Have a linux setup, where I need 2 Python processes to use the same comport, how can I easily share that serial port resource between to separate processes?
Its only the server program that need to open the serial port and then the client shall connect to server and use the same serial port.
Shall i go after socket or something else?
Any point to code example will be appreciated.
Br
Esben
My solution was to build a multiprocessing server handling the serial trafic, Then post message to and from the servers through a queue from my client programs.

Pymodbus and async serial client

I'm trying to read/write some registers to some modbus devices. My software uses Python 3.4 and Twisted, so I wanted a library that integrates with such stack and allows async communications.
I'm trying to use pymodbus to implement a modbus serial client, but the library doesn't seem to offer a ModbusSerialClient anymore?
The following code:
from pymodbus.client.async import ModbusSerialClient as ModbusClient
Will raise an ImportError on Python 3.4 with pymodbus 1.4.0.
Standard examples use ModbusClient with connectTCP, but Twisted doesn't offer a serial endpoint yet.
I've seen there's a StartSerialServer, but it's not clear to me whether and how I could use it.
I'd like to either get a syntax for reading/writing registers via pymodbus, or have suggestion for another working library, as long as it works on Linux with a tty, Python 3.x and Twisted.
You can connect to a serial port using Twisted like this:
from twisted.internet.serialport import SerialPort
from twisted.internet import reactor
port = SerialPort(protocol, deviceName, reactor)
pymodbus offers a modbus protocol. So in the above, protocol should be:
from pymodbus.client.async import ModbusClientProtocol
protocol = ModbusClientProtocol()

Inter-Process Communications between Python and C++ using local file sockets?

I have a c++ program which creates a local socket bound to "/tmp/.mysocket" and waits to receive data from that socket. The way it is set up, raw binary data would be sent to the socket and loaded into the following C++ structure:
struct StateVariable
{
char Name[64];
int E[8];
};
The C++ program listens for input using recvfrom:
int nBytes = recvfrom(SD,&DataReceived,sizeof(StateVariable)/sizeof(char),0,(sockaddr*)&SentFrom,&size);
The server is just using the standard AF_UNIX and SOCK_DGRAM to create the socket.
My questions is relating to python: How do I send data to the local socket bound to /tmp/.mysocket using python? I am not using AF_INET or opening a specific port for this.
I can use python's socket library to describe the socket, but I can't find any resource that discusses binding a socket to a file in python and sending data to that socket. The documentation for the socket library only discusses using AF_INET and SOCK_DGRAM for local sockets bound to a port number at 127.0.0.1, but I'm not doing that.
How do I get python to send data to a socket bound to a file? Is there an example python program that does just that (maybe a client/server pair that demonstrates this functionality)? As long as I can get python to send data to a local file socket, I can figure out the rest.
The Python socket library is a fairly thin wrapper around the socket interface you're familiar with from C++. See socket documentation.
It's going to look something like this:
import socket
import struct
s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
s.connect('/tmp/...')
s.send(struct.pack('64s8i', ...))
You just change AF_INET to AF_UNIX and then .connect(address) and/or .bind(address) methods accept path to a file (instead of (host, port) pair). Other then that everything else works pretty much the same.

Receiving broadcast UDP on a specific interface with Twisted Python

I am working on an Ubuntu 14.04 server with multiple interfaces on different subnets. I am trying to write a twisted(13.2.0) application that listens for broadcasts on one interface only, ignoring the other interfaces.
I am able to receive broadcasts with this code.
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import IN, socket, struct
class BroadcastListener(DatagramProtocol):
def startProtocol(self):
self.transport.getHandle().setsockopt(socket.SOL_SOCKET,
socket.SO_BROADCAST, True)
def datagramReceived(self, datagram, address):
print "Received datagram from %s" % (address[0])
#reactor.listenUDP(65001, BroadcastListener(), interface='192.168.1.1')
reactor.listenUDP(3200, BroadcastListener())
reactor.run()
I am sending test UDP broadcasts from another machine on the 192.168.1.x subnet with socat.
echo Hi |socat - UDP-DATAGRAM:192.168.1.255:3200,broadcast
However, this will receive broadcasts on any interface on the server. I thought it would be specificying the interface in reactor.listenUDP(), as I did the commented call.
If I use the reactor.listenUDP() call that includes the interface, I no longer receive broadcast. I still receive unicasted UDP sent with socat.
echo Hi |socat - UDP-DATAGRAM:192.168.1.1:3200
I can see when specifying the interface that the socket is bound to the interface.
$ netstat -an |grep udp |grep 3200
udp 0 0 10.10.0.1:3200 0.0.0.0:*
But the broadcasts are being dropped. I confirmed with tcpdump the broadcasts are arriving to the server.
What is the correct way to set a UDP listener's interface in twisted python?
I'm assuming you're on Linux here. It seems that bind() won't work because it drops packets not addressed to the interface, which for broadcast packets is all of them. Instead, try the socket option SO_BINDTODEVICE, which may not be in your Python socket module, but has the value 25 on my Linux system and probably on yours (check /usr/include/asm-generic/socket.h). It takes an interface name rather than an IP address, so it should look something like this:
self.transport.getHandle().setsockopt(socket.SOL_SOCKET, 25, "eth0")

Is This a Single Event UDP Socket?

Apologies in advance for I am very new to socket programming, and what little experience I have is within frameworks like Tornado and Flask.
This code, apparently, emits UDP, but I'm not sure where to pick it up, or where it would be picked up.
"""
Simple, asynchronous, nonblocking UDP emitter for Cube metrics.
"""
import json
import socket
from datetime import datetime
def emit(event_type="always", event_data={},
destination='127.0.0.1', port=1180, **kwargs):
event = dict(type=event_type, data=event_data)
# event["time"] = kwargs.get("time", datetime.utcnow().isoformat())
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
s.connect((destination, port))
s.send(json.dumps(event))
s.close()
emit()
Searched the rest of the accompanying library for the destination: 127.0.0.1 and port: 1180, with no results.
Web browser can't connect to 127.0.0.1:1180 (I'm on OS X), although a Flask app is fine at 127.0.0.1:5000.
Found the BinaryTides tutorial on UDP sockets, but they seem to use while statements.
Is this "emitter" just a single event, and if so, where, when and how can I see it's output?
The above method is called via a loop, so on each pass it does generate a single .json object.
It was designed to send to a Cube Server.

Categories

Resources