I have a rfid reader that receive that from serial and TCP. I was having one accepting XML data before as command, but this reader only accept HEX command
I'm using python, I'm not sure how to format the data, I'm able to connect with that script, but no sending nor answer, only a timeout of the remote connection.
Here the documentation of the reader: http://www.chafon.com/Upload/ProductFile/CF-RU5106_160719140435.pdf
Here's my code:
import socket,time,sys
TCP_IP = '192.168.0.238'
TCP_PORT = 7086
BUFFER_SIZE = 20
MESSAGE = b'0x02'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((TCP_IP, TCP_PORT))
except:
print ('failed ' + TCP_IP + ' down')
sys.exit()
s.sendall(MESSAGE)
while data is None:
data = s.recv(BUFFER_SIZE)
print ("No data, waiting....")
time.sleep(0.5)
print ("Data arrived")
incoming = data.decode('utf-8')
print (incoming)
s.close()
Related
I am trying to transfer multiple images over the persistent TCP connection in python. According to my knowledge, this code should work fine but sometimes it shows the following error ValueError: invalid literal for int() with base 10: '6789:'
For each image, I am first trying to send the size of that image to the client.
Can someone please help me with what I am doing wrong or otherwise guide how to do this in other ways
Server code
import socket
import time
import os
port = 6004
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname() # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
print ('Server listening....')
conn, addr = s.accept()
print ('Got connection from', addr)
# data = conn.recv(1024)
# print('Server received', repr(data))
start =time.time()
for i in range(2):
filename="sc" + str(i) + ".jpg"
size = str(os.path.getsize(filename))
try:
conn.send(size.encode())
except:
print('ckckckckckck')
print('filesize', size, len(size))
f = open(filename,'rb')
current=0
size = int(size)
while current <size:
l = f.read(1024)
conn.send(l)
current+=len(l)
print('current',current)
print('l',len(l))
if(current==size):
break
print('close current',current)
f.close()
print('Done sending')
conn.send(b'Thank you for connecting')
#conn.close()
print(time.time()-start)
Client code
import os
import socket
import time # Import socket module
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create a socket object
host = socket.gethostname() # Get local machine name
port = 6004 # Reserve a port for your service.
s.connect((host, port))
s.send(b'Hello server!')
for i in range(2):
data = None
data = s.recv(1024)
data = data.decode()
size = int(data)
print(size)
filename = "sc" + str(i) + ".jpg"
f = open(filename,'wb')
current =0
while current<size:
data = s.recv(1024)
f.write(data)
current+=len(data)
# print('data',len(data))
# print('current',current)
if(current==size):
break
print('close current',current)
f.close()
print('Successfully get the file')
s.close()
print('connection closed')
data = s.recv(5)
You expect that the size is within the first 5 bytes and you expect to get it with one recv. But, the actual size can be less than 5 bytes or more since you don't enforce a specific number of bytes when sending:
conn.send(size.encode())
Thus what could happen here is that the size you read in the client is either too small (if the original size was larger) or that the size used less than 5 bytes and there are already data from the file contents within the 5 bytes you read. And this causes the error you see.
Note that TCP is a byte-stream protocol and not a message protocol, which means that what you send is not necessarily what you recv. Instead the data from multiple send could be read within one recv or a single send could make multiple recv necessary. Thus a better design of your code would make sure that it always writes a fixed length for the length and always makes sure that it got the full length before trying to interpret the data as length.
I am trying to make two small programs; one is a server which will receive mp4 files from a client. The client is just a small program that sends a .mp4 file located in its folder.
I am able to fully send the mp4 file and a file in the same size is created, but for some reason the mp4 gets corrupted or something else goes wrong and I am unable to play the mp4 file in QuickTime player or VLC.
I don't understand this as I am copying all bytes and sending then all in small packets. I would really appreciate some help or some tips.
Server code:
#!/usr/bin/python3
from socket import socket, gethostname
s = socket()
host = gethostname()
port = 3399
s.bind((host, port))
s.listen(5)
n = 0
while True:
print("Listening for connections...")
connection, addr = s.accept()
try:
print("Starting to read bytes..")
buffer = connection.recv(1024)
with open('video_'+str(n), "wb") as video:
n += 1
i = 0
while buffer:
buffer = connection.recv(1024)
video.write(buffer)
print("buffer {0}".format(i))
i += 1
print("Done reading bytes..")
connection.close()
except KeyboardInterrupt:
if connection:
connection.close()
break
s.close()
Client code:
#!/usr/bin/python3
from socket import socket, gethostname, SHUT_WR
s = socket()
host = gethostname()
port = 3399
s.connect((host, port))
print("Sending video..")
with open("test.mp4", "rb") as video:
buffer = video.read()
print(buffer)
s.sendall(buffer)
print("Done sending..")
s.close()
Fix bugs in your server code:
#!/usr/bin/python3
from socket import socket, gethostname
s = socket()
host = gethostname()
port = 3399
s.bind((host, port))
s.listen(5)
n = 0
while True:
print("Listening for connections...")
connection, addr = s.accept()
try:
print("Starting to read bytes..")
buffer = connection.recv(1024)
with open('video_'+str(n)+'.mp4', "wb") as video:
n += 1
i = 0
while buffer:
video.write(buffer)
print("buffer {0}".format(i))
i += 1
buffer = connection.recv(1024)
print("Done reading bytes..")
connection.close()
except KeyboardInterrupt:
if connection:
connection.close()
break
s.close()
fix here:
with open('video_'+str(n)+'.mp4', "wb") as video:
and here:
while buffer:
video.write(buffer)
print("buffer {0}".format(i))
i += 1
buffer = connection.recv(1024)
I want to send an image (.pgm) via TCP as soon as it is written to the ramdisk. For this I'm working with pyinotify and sockets. After the picture is sent I would like to tell the server to stop now.
Everything works fine but the last part gives me following error:
if data.decode('utf-8') == 'stop': UnicodeDecodeError: 'utf-8' codec can't
decode byte 0x88 in position 319: invalid start byte
Client:
import pyinotify
import socket
import traceback
import sys
class ModHandler(pyinotify.ProcessEvent):
def __init__(self, socket, buffer_size):
self.socket = socket
self.buffer_size = buffer_size
def process_IN_CLOSE_WRITE(self, event):
try:
self.socket.send(bytes(event.pathname, encoding='utf-8'))
file = open(event.pathname, "rb")
line = file.read(self.buffer_size)
while(line):
self.socket.send(line)
line = file.read(self.buffer_size)
except Exception:
traceback.print_exc()
finally:
try:
self.socket.send(bytes('stop', encoding='utf-8'))
print("done")
file.close
except Exception:
traceback.print_exc()
class TCPStream():
def __init__(self, ip, port, buffer_size):
self.ip = ip
self.port = port
self.buffer_size = buffer_size
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.socket.connect((self.ip, self.port))
except Exception:
traceback.print_exc()
def __del__(self):
try:
self.socket.close()
except Exception:
traceback.print_exc()
stream = TCPStream('127.0.0.1', 5005, 1024)
handler = ModHandler(stream.socket, stream.buffer_size)
wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm, handler)
wd_value = wm.add_watch("/media/ram_disk", pyinotify.IN_CLOSE_WRITE)
if wd_value["/media/ram_disk"] <= 0:
print("can't add watchmanager to the ram_disk... insufficient
authorization? another watchmanager already running?")
sys.exit(0)
notifier.loop()
Server:
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 5005
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
print("connection address: ", addr)
path = conn.recv(BUFFER_SIZE).decode('utf-8')
filename = path.split("/")
with open(filename[3], 'wb') as f:
data = conn.recv(BUFFER_SIZE)
while data:
print("receiving...")
f.write(data)
data = conn.recv(BUFFER_SIZE)
if not data:
break
if data.decode('utf-8') == 'stop':
f.close()
print("done")
break
conn.close()
The goal is to have a constant TCP stream of images written to the ramdisk. Therefore I wanted to communicate via Bytes with the server to tell him what to do. It seems that after the first picture gets transmitted it breaks somehow. Any help is appreciated!
What if four consecutive bytes in your image at the beginning of a buffer happen to match the ASCII (and UTF-8) characters s t o p? Also, how does the receiving side know when the file name ends, and the file data starts?
You should create a binary encoding that frames the various bits of your data. This makes the whole process nicely deterministic. That's often best done with the struct module's pack and unpack methods. Given a file you want to send, client side:
import os
import struct
...
pathname = event.pathname.encode('utf-8') # Encode pathname into bytes
pathname_len = len(pathname)
file = open(event.pathname, "rb")
filesize = os.path.getsize(event.filename) # Get file size
# Encode size of file name, and size of file into a binary header
header_format = struct.Struct("!II")
header = header_format.pack(pathname_len, filesize)
self.socket.sendall(header)
self.socket.sendall(pathname)
while True:
line = file.read(self.buffer_size)
if not line: break # EOF
self.socket.sendall(line)
# (Remove sending of 'stop' from finally block)
Note the use of sendall to ensure that the entire buffer gets sent (it is legal for send to send only part of a buffer but that can result in missing bytes if you don't account for it).
Server side will look something like this:
import struct
...
def recv_exactly(s, buffer_len):
""" This is the converse of sendall """
data = b''
rem_bytes = buffer_len
while rem_bytes > 0:
buf = s.recv(rem_bytes)
if not buf:
raise Exception("Received EOF in middle of block")
data += buf
rem_bytes -= len(buf)
return data
conn, addr = s.accept()
...
header_format = struct.Struct("!II")
# Receive exactly the bytes of the header
header = recv_exactly(conn, header_format.size)
pathname_len, file_len = header_format.unpack(header)
path = recv_exactly(conn, pathname_len)
filename = path.split("/")
...
rem_bytes = file_len
while rem_bytes > 0:
data = conn.recv(min(rem_bytes, BUFFER_SIZE))
if not data:
raise Exception("Received EOF in middle of file")
f.write(data)
rem_bytes -= len(data)
Another important advantage of this model is that you now have a clear notion of the boundary between one file and the next (without having a "signal value" that might appear in the data). The receiver always knows exactly how many bytes remain until the end of the current file, and the sender can simply move on to send a new header, pathname, and file without opening a new connection.
I want to send a json data to client with json values taken from variables.
Please help to suggest how I can achieve this?
I have tried below code on server side but it does not work
# next create a socket object
s = socket.socket()
print("Socket successfully created")
s.bind(('', port))
print("socket binded to %s" % (port))
# put the socket into listening mode
s.listen(5)
print("socket is listening")
message = {'studentname': 'name', 'studentmark': 'marks'}
s,addr = s.accept()
while True:
tmp = s.recv(1024)
message += tmp
d = json.loads(message)
s.send(d)
print(d)
I'm learning python 3 and is my first language, so sorry if it's a silly question, but I cant't find out why it doesn't work...
I'm testing a simple echo client/server application. According to my book, I first created a file named tincanchat:
import socket
HOST = ''
PORT = 4040
def create_listen_socket(host, port):
""" Setup the sockets our server will receive connection
requests on """
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((host, port))
sock.listen(100)
return sock
def recv_msg(sock):
""" Wait for data to arrive on the socket, then parse into
messages using b'\0' as message delimiter """
data = bytearray()
msg = ''
# Repeatedly read 4096 bytes off the socket, storing the bytes
# in data until we see a delimiter
while not msg:
recvd = sock.recv(4096)
if not recvd:
# Socket has been closed prematurely
raise ConnectionError()
data = data + recvd
if b'\0' in recvd:
# we know from our protocol rules that we only send
# one message per connection, so b'\0' will always be
# the last character
msg = data.rstrip(b'\0')
msg = msg.decode('utf-8')
return msg
def prep_msg(msg):
""" Prepare a string to be sent as a message """
msg += '\0'
return msg.encode('utf-8')
def send_msg(sock, msg):
""" Send a string over a socket, preparing it first """
data = prep_msg(msg)
sock.sendall(data)
Then, I wrote the server:
import tincanchat
HOST = tincanchat.HOST
PORT = tincanchat.PORT
def handle_client(sock, addr):
""" Receive data from the client via sock and echo it back """
try:
msg = tincanchat.recv_msg(sock) # Blocks until received
# complete message
print('{}: {}'.format(addr, msg))
tincanchat.send_msg(sock, msg) # Blocks until sent
except (ConnectionError, BrokenPipeError):
print('Socket error')
finally:
print('Closed connection to {}'.format(addr))
sock.close()
if __name__ == '__main__':
listen_sock = tincanchat.create_listen_socket(HOST, PORT)
addr = listen_sock.getsockname()
print('Listening on {}'.format(addr))
while True:
client_sock, addr = listen_sock.accept()
print('Connection from {}'.format(addr))
handle_client(client_sock, addr)
And the client:
import sys, socket
import tincanchat
HOST = sys.argv[-1] if len(sys.argv) > 1 else '127.0.0.1'
PORT = tincanchat.PORT
if __name__ == '__main__':
while True:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
print('\nConnected to {}:{}'.format(HOST, PORT))
print("Type message, enter to send, 'q' to quit")
msg = input()
if msg == 'q': break
tincanchat.send_msg(sock, msg) # Blocks until sent
print('Sent message: {}'.format(msg))
msg = tincanchat.recv_msg(sock) # Block until
# received complete
# message
print('Received echo: ' + msg)
except ConnectionError:
print('Socket error')
break
finally:
sock.close()
print('Closed connection to server\n')
I run the server, then the client, which connects with the server and asks for input. At this point, it returns this error:
Connected to 127.0.0.1:4040
Type message, enter to send, 'q' to quit
Hello
Closed connection to server
Traceback (most recent call last):
File "C:\xxxxxxxxx\1.2-echo_client-uni.py", line 22, in <module>
except ConnectionError:
NameError: name 'ConnectionError' is not defined
Where is the problem?
Thanks in advance :)
If u want to catch the specified Errors or Exceptions, U should import them first.
What you could do for for example is:
from requests.exceptions import ConnectionError
try:
r = requests.get("http://example.com", timeout=0.001)
except ConnectionError as e: # This is the correct syntax
print e
r = "No response"
In this case your program will not return 'NameError'