I am using Python3 to forward incoming data form a tcp connection to a character device.
The code below is the part where I receive the data from the tcp stream. The data should all be interpreted as ASCII. Once a datagram of shape [...] is complete it should be sent to a character device file.
def tcp2devWorker(devwrt,tcp):
tcp2devbuf="";
while (1):
chunk=str(tcp.recv(64));
for b in range(len(chunk)):
if chunk[b]=="[":
tcp2devbuf="[";
elif chunk[b]=="]":
tcp2devbuf+="]";
print("From TCP: ",tcp2devbuf);
devwrt.write(tcp2devbuf);
devwrt.flush();
else:
tcp2devbuf+=str(chunk[b]);
Print shows 'b' in front of every chunk. I thought it is an artifact of print. But is also shows in the character device. Output of print:
From TCP: [)!!!!!!!!!!!!!!|SEFMTE8K#######################################'b'################################################################'b'################################################################'b'################################################################'b'#############################################################]
I read it has to do with the encoding but I dont get the concept right. Whatever way I encode and decode, can cannot get rid of the 'b's.
Can somebody point me at what I am missing?
If you just want to remove 'b' from tcp2devbuf. Then you can use tcp2devbuf.replace("'b'","").
Like this
def tcp2devWorker(devwrt,tcp):
tcp2devbuf="";
while (1):
chunk=str(tcp.recv(64));
for b in range(len(chunk)):
if chunk[b]=="[":
tcp2devbuf="[";
elif chunk[b]=="]":
tcp2devbuf+="]";
tcp2tcp2devbuf = devbuf.replace("'b'","") # <---
print("From TCP: ",tcp2devbuf);
devwrt.write(tcp2devbuf);
devwrt.flush();
else:
tcp2devbuf+=str(chunk[b]);
Related
m trying to create a tool that help to simulate key press
but at part of this code mentioned below, the program gets stuck and its not proceeding
ser = serial.Serial(ACM)
ser.baudrate = 115200
ser.timeout = None
ser.flushInput()
ser.flushOutput()
ser.write(cmd)
p = ser.readline()
pr = p.decode("utf-8")
print(cmd)
print(pr)
ser.close()
print("Closed")
" ser.readline() is not reading the output of serial com /dev/ttyACM*
Thanks
The PySerial documentation is unmistakable:
Be careful when using readline(). Do specify a timeout when opening
the serial port otherwise it could block forever if no newline
character is received.
You define: ser.timeout = None so what exactly do you expect your program to do, but block forever if you don't receive a newline?
Either make sure the sent lines are terminated or use a reasonable timeout.
Good afternoon.
I get the example below from SSH:
b"rxmop:moty=rxotg;\x1b[61C\r\nRADIO X-CEIVER ADMINISTRATION\x1b[50C\r\nMANAGED OBJECT DATA\x1b[60C\r\n\x1b[79C\r\nMO\x1b[9;19HRSITE\x1b[9;55HCOMB FHOP MODEL\x1b[8C\r\nRXOTG-58\x1b[10;19H54045_1800\x1b[10;55HHYB"
I process ssh.recv (99999) .decode ('ASCII')
but some characters are not decoded for example:
\x1b[61C
\x1b[50C
\x1b[9;55H
\x1b[9;19H
The article below explains that these are ANSI escape codes that appear since I use invoke_shell. Previously everything worked until it moved to another server.
Is there a simple way to get rid of junk values that come when you SSH using Python's Paramiko library and fetch output from CLI of a remote machine?
When I write to the file, I also get:
rxmop:moty=rxotg;[61C
RADIO X-CEIVER ADMINISTRATION[50C
MANAGED OBJECT DATA[60C
[79C
MO[9;19HRSITE[9;55HCOMB FHOP MODEL[8C
RXOTG-58[10;19H54045_1800[10;55HHYB
If you use PuTTY everything is clear and beautiful.
I can't get away from invoke_shell because the connection is being thrown from one server to another.
Sample code below:
# coding:ascii
import paramiko
port = 22
data = ""
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=host, username=user, password=secret, port=port, timeout=10)
ssh = client.invoke_shell()
ssh.send("rxmop:moty=rxotg;\n")
while data.find("<") == -1:
time.sleep(0.1)
data += ssh.recv(99999).decode('ascii')
ssh.close()
client.close()
f = open('text.txt', 'w')
f.write(data)
f.close()
The normal output is below:
MO RSITE COMB FHOP MODEL
RXOTG-58 54045_1800 HYB BB G12
SWVERREPL SWVERDLD SWVERACT TMODE
B1314R081D TDM
CONFMD CONFACT TRACO ABISALLOC CLUSTERID SCGR
NODEL 4 POOL FLEXIBLE
DAMRCR CLTGINST CCCHCMD SWVERCHG
NORMAL UNLOCKED
PTA JBSDL PAL JBPTA
TGFID SIGDEL BSSWANTED PACKALG
H'0001-19B3 NORMAL
What can you recommend in order to return normal output, so that all characters are processed?
Regular expressions do not help, since the structure of the record is shifted, then characters from certain positions are selected in the code.
PS try to use ssh.invoke_shell (term='xterm') don't work.
There is an answer here:
How can I remove the ANSI escape sequences from a string in python
There are other ways...
https://unix.stackexchange.com/questions/14684/removing-control-chars-including-console-codes-colours-from-script-output
Essentially, you are 'screen-scraping' input, and you need to strip the ANSI codes. So, grab the input, and then strip the codes.
import re
... (your ssh connection here)
data = ""
while data.find("<") == -1:
time.sleep(0.1)
chunk = ssh.recv(99999)
data += chunk
... (your ssh connection cleanup here)
ansi_escape = re.compile(r'\x1B(?:[#-Z\\-_]|\[[0-?]*[ -/]*[#-~])')
data = ansi_escape.sub('', data)
I have written the code for transferring an audio file from client to server using udp (python).
Now I am required to introduce reliability in the codes of UDP. The instructions are given as:
"You will be required to implement following to make UDP reliable:
(a) Sequence and acknowledge numbers
(b) Re-transmission (selective repeat)
(c) Window size of 5-10 UDP segments (stop n wait)
(d) Re ordering on receiver side "
THE SENDER THAT IS CLIENT CODE IS GIVEN BELOW
from socket import *
import time
# Assigning server IP and server port
serverName = "127.0.0.1"
serverPort = 5000
# Setting buffer length
buffer_length = 500
# Assigning the audio file a name
my_audio_file = r"C:\Users\mali.bee17seecs\PycharmProjects\TestProject\Aye_Rah-e-Haq_Ke_Shaheedo.mp3"
clientSocket = socket(AF_INET, SOCK_DGRAM)
# Opening the audio file
f = open(my_audio_file, "rb")
# Reading the buffer length in data
data = f.read(buffer_length)
# While loop for the transfer of file
while data:
if clientSocket.sendto(data, (serverName, serverPort)):
data = f.read(buffer_length)
time.sleep(0.02) # waiting for 0.02 seconds
clientSocket.close()
f.close()
print("File has been Transferred")
THE RECEIVER THAT IS SERVER CODE IS GIVEN BELOW
from socket import *
import select
# Assigning server IP and server port
serverName = "127.0.0.1"
serverPort = 5000
# Setting timeout
timeout = 3
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind((serverName, serverPort))
# While loop for the receiving of file
while True:
data, serverAddress = serverSocket.recvfrom(1024)
if data:
file = open(r"C:\Users\mali.bee17seecs\PycharmProjects\TestProject\Aye_Rah-e-Haq_Ke_Shaheedo.mp3",
"wb")
while True:
ready = select.select([serverSocket], [], [], timeout)
if ready[0]:
data, serverAddress = serverSocket.recvfrom(500)
file.write(data)
else:
file.close()
print("File has been Received")
break
Before answer each request, you should know that we build a reliable UDP by adding some specific infomation before the real content, which you can think as a application layer head. We use them to do some control or collect infomation like TCP does in traffic layer by the head part. It may look like below:
struct Head {
int seq;
int size;
}
(a) Sequence and acknowledge numbers
If you're familar with TCP, it is not hard. You can set seq and when the other side receive it, the controller will judge it and to check if we need to do b/d.
(b) Re-transmission (selective repeat) & (d) Reordering on receiver side
They are familiar to realise, using GBN/ARQ/SACK algorithm to do retransmission, using some simple algorithm like sorting to do reording.
(c) Window size of 5-10 UDP segments (stop n wait)
This part need to do some thing like traffic control that TCP does. I don't how complex you want to do, it's can be really complex or simple, it depends on you.
I tried to create a server that receives commands from the client
And to identify which command the client wrote I used if & elif
But when I run the program and write a command from the client, only the first command works (the command on the if) and if I try another command (from elif & else)
The system just doesn't respond (like she's waiting for something)
The Server Code:
import socket
import time
import random as rd
soc = socket.socket()
soc.bind(("127.0.0.1", 7777))
soc.listen(5)
(client_socket, address) = soc.accept()
if(client_socket.recv(4) == b"TIME"):
client_socket.send(time.ctime().encode())
elif(client_socket.recv(4) == b"NAME"):
client_socket.send(b"My name is Test Server!")
elif(client_socket.recv(4) == b"RAND"):
client_socket.send(str(rd.randint(1,10)).encode())
elif(client_socket.recv(4) == b"EXIT"):
client_socket.close()
else:
client_socket.send(b"I don't know what your command means")
soc.close()
The Client Code:
import socket
soc = socket.socket()
soc.connect(("127.0.0.1", 7777))
client_command_to_the_server = input("""
These are the options you can request from the server:
TIME --> Get the current time
NAME --> Get the sevrer name
RAND --> Get a Random int
EXIT --> Stop the connect with the server
""").encode()
soc.send(client_command_to_the_server)
print(soc.recv(1024))
soc.close()
if(client_socket.recv(4) == b"TIME"):
client_socket.send(time.ctime().encode())
This will check the first 4 byte received from the server
elif(client_socket.recv(4) == b"NAME"):
client_socket.send(b"My name is Test Server!")
This will check the next 4 bytes received from the server. Contrary to what you assume it will not check the first bytes again since you called recv to read more bytes. If there are no more bytes (likely, since the first 4 bytes are already read) it will simply wait. Instead of calling recv for each comparison you should call recv once and then compare the result against the various strings.
Apart from that: recv will only return up to the given number of bytes. It might also return less.
So I'm connected to an IRC chat using socket.connec
I log in by passing my variables via socket.send
The log in is successful and then I sit in a while true loop using
Socket.recv(1024)
If I just continually print the response everything looks fine, but let's say I want to add to the end of the string... I noticed that socket.recv doesn't always get the full message (only grabs up to 1024 as expected) and the remainder of the message is in the next iteration of the loop.
This makes its it impossible to process the feedback line by line.
Is there a better way to constantly read the data without it getting trunked? Is it possible to figure out the size of the response before receiving it so the buffer can be set dynamically?
TCP is a stream-based protocol. Buffer the bytes received and only extract complete messages from the stream.
For complete lines, look for newline characters in the buffer.
Example server:
import socket
class Client:
def __init__(self,socket):
self.socket = socket
self.buffer = b''
def getline(self):
# if there is no complete line in buffer,
# add to buffer until there is one.
while b'\n' not in self.buffer:
data = self.socket.recv(1024)
if not data:
# socket was closed
return ''
self.buffer += data
# break the buffer on the first newline.
# note: partition(n) return "left of n","n","right of n"
line,newline,self.buffer = self.buffer.partition(b'\n')
return line + newline
srv = socket.socket()
srv.bind(('',5000))
srv.listen(1)
conn,where = srv.accept()
client = Client(conn)
print(f'Client connected on {where}')
while True:
line = client.getline()
if not line:
break
print(line)
Example client:
s=socket()
s.connect(('127.0.0.1',5000))
s.sendall(b'line one\nline two\nline three\nincomplete')
s.close()
Output on server:
Client connected on ('127.0.0.1', 2667)
b'line one\n'
b'line two\n'
b'line three\n'