How to send bytes using python (example please!) - python

I'm trying to create a simple thingermajigger in python at the moment just to test out sending UDP packets over a socket. I think that I'm getting my script perfectly fine other than using the socket.sendto command. I keep getting errors regarding the portion where "bytes" would go... either TypeError: an interget is required, or when I make it an interget TypeError: a string is required. Could someone provide me with an example of how to send a byte?
the point in my script where I'm getting the error is as follows... please fill out an example as well as a possible explanation / documentation for a newbie.
#full script as requested
import socket
import random
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
butes = random._urandom(1024)
#originally found this as a way to generate bytes to send, but it didn't work out
print("target IP: ")
ip = input()
print("port: ")
port = input()
while 1:
sock.sendto(butes, (ip, port))
print("Sent %s amount of packets to %s at port %s." % (sent,ip,port))
sent += 1

In your posted code, port is a str, you should use port = int(input())
Aside: b'0x2E' which you had in the original question is 4 characters. If you mean chr(0x2E) you can also write '\x2E'

Related

About the issue that the character string is broken in TCP/IP communication between different machines

I tried TCP/IP communication between the same machine and TCP/IP communication between different machines.
First of all, I tried communication in the same Windows machine.The server and client code used is:
TCP_server.py
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('', 50001))
s.listen(1)
while True:
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(30000)
if not data:
break
if len(data.decode('utf-8')) < 35:
print("error")
break
print(data.decode('utf-8')+"\n")
TCP_client.py
# -*- coding : UTF-8 -*-
import socket
target_ip = "192.168.1.5"
target_port = 50001
buffer_size = 4096
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client.connect((target_ip,target_port))
message = b'123456789101112131415161718192021222324252627282930\n'
while True:
tcp_client.send(message)
The IP address of my Windows machine is 192.168.1.5, so the above code works. And it executed successfully without any error. The printed string is shown in the image below.
But when I tried to communicate with Mac and Windows using the exact same code, I had a problem. I used a Mac for the client and Windows for the server.The character string output on the server side is as follows.
As you can see from the image above, it is normally printed normally, but sometimes a line break is made and the character string is divided.
And my server-side code says that if the number of characters is less than 35, it will print error. However, error is not printed in this execution result.In other words, communication is not performed twice, but line breaks are inserted in one communication.
Is it possible to avoid this problem? Do I always have to be aware of line breaks when sending from another machine over TCP/IP?
I'm only using Python in this sample, but I had a similar problem using iOS's Swift for client-side code. So I would like to know a general solution.
There is no line break added by transmission of the data. This line break is instead added by the server code:
print(data.decode('utf-8')+"\n")
Both the print itself causes a line break and then you also add another one.
In general you are assuming that each send has a matching recv. This assumption is wrong. TCP is a byte stream and not a message stream and the payloads from multiple send might be merged together to reduce the overhead of sending and it might also cause a "split" into a single "message".
This is especially true when sending traffic between machines since the bandwidth between the machines is less than the local bandwidth and the MTU of the data layer is also much smaller.
Given that you have to first collect your "messages" at the server side. Only after you've got a complete "message" (whatever this is in your case) you should decode('utf-8'). Otherwise your code might crash when trying to decode a character which has a multi-byte UTF-8 encoding but where not all bytes were received yet.

How to send data over tcp to ESP8266 with python?

I want to send data from my computer to ESP8266 over TCP. I wanted to do this with python. I programmed ESP with arduino-language with libraries for it, and reciving is simply:
while(client.available()){
String in = client.readStringUntil('~');
//i use '~' instead of '\n' as end character because i often can't send '\n' from tcp android apps
...
}
I use built-in socket library for python, this is how i try to send data:
server_ip = '192.168.1.100'
server_port = 3000
soc = socket.socket()
soc.connect((server_ip, server_port))
soc.send("mydata")
but i'm still getting error "TypeError: a bytes-like object is required, not 'str'". I tried .sendall etc, and sometimes they work, but then my ESP restarts for some reason, maybe encoding? Could someone give me staight path to just send basic string, even with ascii-only characters?
Ok i did
.sendall(text.encode('utf-8')
and figured out that i forget about '~', now everything works :)
Check out this project at github for communication between nodemcu and python over ip
https://github.com/wahajmurtaza/NodeMCU-Python-Wifi

Python sockets error TypeError: a bytes-like object is required, not 'str' with send function

I am trying to create a program that will open a port on the local machine and let others connect into it via netcat. My current code is.
s = socket.socket()
host = '127.0.0.1'
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print('Got connection from', addr)
c.send('Thank you for connecting')
c.close()
I am new to Python and sockets. But when I run this code it will allow me to send a netcat connection with the command:
nc 127.0.0.1 12345
But then on my Python script I get the error for the c.send:
TypeError: a bytes-like object is required, not 'str'
I am basically just trying to open a port, allow netcat to connect and have a full shell on that machine.
The reason for this error is that in Python 3, strings are Unicode, but when transmitting on the network, the data needs to be bytes instead. So... a couple of suggestions:
Suggest using c.sendall() instead of c.send() to prevent possible issues where you may not have sent the entire msg with one call (see docs).
For literals, add a 'b' for bytes string: c.sendall(b'Thank you for connecting')
For variables, you need to encode Unicode strings to byte strings (see below)
Best solution (should work w/both 2.x & 3.x):
output = 'Thank you for connecting'
c.sendall(output.encode('utf-8'))
Epilogue/background: this isn't an issue in Python 2 because strings are bytes strings already -- your OP code would work perfectly in that environment. Unicode strings were added to Python in releases 1.6 & 2.0 but took a back seat until 3.0 when they became the default string type. Also see this similar question as well as this one.
You can decode it to str with receive.decode('utf_8').
You can change the send line to this:
c.send(b'Thank you for connecting')
The b makes it bytes instead.
An alternative solution is to introduce a method to the file instance that would do the explicit conversion.
import types
def _write_str(self, ascii_str):
self.write(ascii_str.encode('ascii'))
source_file = open("myfile.bin", "wb")
source_file.write_str = types.MethodType(_write_str, source_file)
And then you can use it as source_file.write_str("Hello World").

Unpacking UDP packets python

I am receiving UDP packets over wifi running a simple python script on a PC. The server and the PC are in the same subnet.
The server is sending 15 uint_8 (4 bytes each) every 20 ms or so. The data received seems to be corrupted (non Hex values). Any feedback why this could be happening greatly appreciated.
For example I get something like this,
'\xb3}fC\xb7v\t>\xc8X\xd2=g\x8e1\xbf\xe6D3\xbf\x00\x00\x13\xc3\xc8g\x1b#\xc2\x12\xb2B\x01\x000=\x02\xc0~?\x01\x00\x94<\x00\x00\x00\x00\x00\x00\x00\x00\x00
#\x9c\xbe\xac\xc9V#', ('192.168.4.1', 4097))
The script is attached here.
from socket import *
import time
HOST = '192.168.4.10'
PORT = 9048
address = (HOST, PORT)
client_socket = socket(AF_INET, SOCK_DGRAM) #Set Up the Socket
client_socket.bind((HOST, PORT))
client_socket.settimeout(5) #only wait 5 second for a response, otherwise timeout
while(1): #Main Loop
single_var = client_socket.recvfrom(1024)
print single_var #Print the response from Arduino
time.sleep(10/1000000) # sleep 10 microseconds
The print statement doesn't know that you want hex output, so it interprets hex values that have valid character representations as characters. If you want to print it as hex bytes, see the solution in Print a string as hex bytes.
i.e. do:
print ":".join("{:02x}".format(ord(c)) for c in single_var)

Telnetlib: Not receiving anything

I have a question regarding Python`s telnetlib-Library.
import telnetlib
message= ('\x02'+'DD'+'\x03')
print message
tn = telnetlib.Telnet('IP','PORT')
tn.write(message)
while True:
data = tn.read_all()
if data:
print data
I want to communicate with a data-logger. The data-logger expects commands which looks like this:
STX + command + ETX
By sending the STX+command+ETX-phrase via Putty / telnet to the data-logger, the data logger "answers", e.g. by sending the current time.
Now, I want to send the same thing via python script to the logger. Unfortuantely, I do not receive any answer in the python shell, just a white space.
Can you please help me?
Regard,
Phil
Using doblequote for special character code
message= ("\x02"+'DD'+"\x03")
Have u already declare IP address and port number.
tn = telnetlib.Telnet('192.168.0.10',2021)

Categories

Resources