How can i obtain the data sent via bluetooth? Kivy application - python

This is my little Kivy project. My goal for now is to send a string (message) to my PC and print it print(message):
main.py
import kivy
from kivy.app import App
from kivy.uix.button import Button
from bluetooth import AndroidBluetoothClass
kivy.require("2.1.0")
# class in which we are creating the button
class ButtonApp(App):
def build(self):
# use a (r, g, b, a) tuple
self.btn = Button(text="Push Me !",
font_size="20sp",
background_color=(1, 1, 1, 1),
color=(1, 1, 1, 1),
size=(32, 32),
size_hint=(.2, .2),
pos=(300, 250))
# bind() use to bind the button to function callback
self.btn.bind(on_press=self.callback)
return self.btn
# callback function tells when button pressed
def callback(self, event):
try:
a = AndroidBluetoothClass()
a.getAndroidBluetoothSocket('MSI')
a.BluetoothSend("Balls")
except Exception as e:
self.btn.text = str(e)
root = ButtonApp()
root.run()
bluetooth.py (src: Can't send bluetooth from Kivy App on Android)
from jnius import autoclass
class AndroidBluetoothClass:
def getAndroidBluetoothSocket(self, DeviceName):
paired_devices = self.BluetoothAdapter.getDefaultAdapter().getBondedDevices().toArray()
socket = None
for device in paired_devices:
if device.getName() == DeviceName:
socket = device.createRfcommSocketToServiceRecord(
self.UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
self.ReceiveData = self.BufferReader(self.InputStream(socket.getInputStream()))
self.SendData = socket.getOutputStream()
socket.connect()
self.ConnectionEstablished = True
print('Bluetooth Connection successful')
return self.ConnectionEstablished
def BluetoothSend(self, Message, *args):
if self.ConnectionEstablished == True:
self.SendData.write(Message)
else:
print('Bluetooth device not connected')
def BluetoothReceive(self, *args):
DataStream = ''
if self.ConnectionEstablished == True:
DataStream = str(self.ReceiveData.readline())
return DataStream
def __init__(self):
self.BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter')
self.BluetoothDevice = autoclass('android.bluetooth.BluetoothDevice')
self.BluetoothSocket = autoclass('android.bluetooth.BluetoothSocket')
self.UUID = autoclass('java.util.UUID')
self.BufferReader = autoclass('java.io.BufferedReader')
self.InputStream = autoclass('java.io.InputStreamReader')
self.ConnectionEstablished = False
def __del__(self):
print('class AndroidBluetooth destroyer')
How can i collect the data sent by my android application? There is a way?
Hope you can help me :D
If you need it
buildozer.spec
[app]
title = wtheeel
version = 1.1
package.name = wtheeel
package.domain = test.able
source.dir = .
source.include_exts = py,png,jpg,kv,atlas
android.permissions =
FOREGROUND_SERVICE,
BLUETOOTH,
BLUETOOTH_ADMIN,
BLUETOOTH_SCAN,
BLUETOOTH_CONNECT,
BLUETOOTH_ADVERTISE,
ACCESS_FINE_LOCATION
requirements = kivy==2.1.0,python3,able_recipe
services = Able:service.py:foreground
android.accept_sdk_license = True
# android.api = 31
# android.minapi = 31
[buildozer]
warn_on_root = 1
# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2
I tried with the socket library but i was already expecting a bad news.
server.py
import socket
hostMACAddress = 'my mac address' # The MAC address of a Bluetooth adapter on the server. The server might have multiple Bluetooth adapters.
port = 4 # 3 is an arbitrary choice. However, it must match the port used by the client.
backlog = 1
size = 1024
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.bind((hostMACAddress, port))
s.listen(backlog)
try:
client, address = s.accept()
while 1:
data = client.recv(size)
if data:
print(data)
client.send(data)
except:
print("Closing socket")
client.close()
s.close()

Related

Cannot connect the python application with sockets properly to a public IP address

I developed a simple chat app that allows users to connect to a server and chat. This is the code for the server.
import os
from datetime import datetime
def log_file_name():
n = str(datetime.now())
m = n.replace(':','_').replace(' ','---')
l = m.split('.')[0]
l = f'{l}.txt'
return l
HOST = '127.0.0.1'
PORT = 10001
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#print(type(server_socket))
server.bind((HOST, PORT))
server.listen()
print('server_initiated...')
logfile = os.path.join('logs', log_file_name())
with open(logfile, 'w') as fh:
fh.write(f'{str(datetime.now())} log file initiated!\n\n')
clients = []
nicknames = []
#broadcast
def broadcast(message):
#print(clients)
for client in clients:
client.send(message)
def handle(client):
while True:
try:
message = client.recv(1024)
#print(f'{nicknames[clients.index(client)]} says {message}')
broadcast(message)
with open(logfile, 'a') as fh:
fh.write(f"{nicknames[clients.index(client)]} says {message.decode('utf-8')}\n")
except Exception:
index = clients.index(client)
clients.remove(client)
client.close()
left_nick = nicknames[index]
leaving_notes = f"{left_nick} just left the chat!! -- time {str(datetime.now()).split(' ')[1].split('.')[0]}"
broadcast(leaving_notes.encode('utf-8'))
with open(logfile,'a') as fh:
fh.write(f'{leaving_notes}\n')
nicknames.remove(left_nick)
break
#recieve message
def recieve():
while True:
client, address = server.accept()
#print(dir(client))
#print(client._io_refs)
#print(f'Connected with {str(address)}!!')
with open(logfile, 'a') as fh:
fh.write(f'Connected with {str(address)}!!\n')
client.send('Nickname'.encode('utf-8'))
nickname = client.recv(512).decode('utf-8')
nicknames.append(nickname)
clients.append(client)
#print(f'from 1st step clients are {clients}')
#print(f'Nickname of the client is {nickname}')
with open(logfile, 'a') as fh:
fh.write(f'Nickname of the client is {nickname}\n')
broadcast(f'Notice from server!! {nickname} just connected to the server!\n'.encode('utf-8'))
client.send(f'Connected to the server as {nickname}\n'.encode('utf-8'))
thread = threading.Thread(target=handle, args=(client,))
thread.start()
recieve()
Then I exposed that port to public using ngrok (ngrok http 10001), and it generated a public ip for me.
I coded a simple client gui using tkinter and I tried to connect the socket in to to above ngrok server I got. But I cannot broadcast messages. When I try to broadcast a message the GUI automatically closes. The reason is it meets a ConnectionAbortError.
Code for client-
import threading
import tkinter
import socket
import tkinter.simpledialog
import tkinter.scrolledtext
import os
#HOST = socket.gethostbyname(socket.gethostname())
#PORT = 10001
HOST = '3a7d-2402-4000-1245-cd8a-5d64-9c3f-25a3-79a4.in.ngrok.io'
PORT = 443 #or 80
class Client:
def __init__(self,host,port):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, port))
msg = tkinter.Tk()
msg.withdraw()
self.nickname = tkinter.simpledialog.askstring('Nickname', 'Please enter a nickname', parent=msg)
self.gui_done = False
self.running = True
gui_t=threading.Thread(target=self.gui_loop)
recieve_t=threading.Thread(target=self.recieve)
gui_t.start()
recieve_t.start()
def gui_loop(self):
self.win = tkinter.Tk()
self.win.configure(bg='lightgray')
self.chat_label = tkinter.Label(self.win, text='Chat:', bg='lightgray')
self.chat_label.config(font=('Arial',12))
self.chat_label.pack(padx=20, pady=5)
self.text_area = tkinter.scrolledtext.ScrolledText(self.win)
self.text_area.pack(padx=20,pady=5)
#self.text_area.config(state='disabled')
self.msg_label = tkinter.Label(self.win, text='Message:', bg='lightgray')
self.msg_label.config(font=('Arial', 12))
self.msg_label.pack(padx=20, pady=5)
self.input_area = tkinter.Text(self.win, height=3)
self.input_area.pack(padx=20, pady=5)
self.send_button = tkinter.Button(self.win, text='Send', command=self.write)
self.send_button.config(font=('Arial', 12))
self.send_button.pack(padx=20, pady=5)
self.gui_done = True
self.win.protocol('WM_DELETE_WINDOW', self.stop)
self.win.mainloop()
def write(self):
message = f"{self.nickname}: {self.input_area.get('1.0', 'end')}"
#print(message)
self.sock.send(message.encode('utf-8'))
self.input_area.delete('1.0','end')
def recieve(self):
while self.running:
try:
message = self.sock.recv(1024).decode('utf-8')
print(message)
if message == 'Nickname':
self.sock.send(self.nickname.encode('utf-8'))
else:
if self.gui_done:
#print('I hit here often')
self.text_area.config(state='normal')
self.text_area.insert('end', message)
self.text_area.yview('end')
#self.text_area.config(status='disabled') #never use this inside a loop, disabled blocks the code....
except ConnectionAbortedError: #when closed the window I come here..
print('Am i here?')
#break
os._exit(0)
#break
except:
break
print('Error')
self.sock.close()
break
def stop(self):
self.running = False
self.win.destroy()
self.sock.close()
exit(0)
client = Client(HOST, PORT)
If you run this please make sure to create a directory called logs to save the log of communication. Or else it will give an error(You can try it on localhost). I think I am doing something that doesn't work here. Can you point it out to me? or can you give me an alternative way of doing it?

TimeoutError: [WinError 10060] python socket and gui tkinter server connects to the client

from tkinter import *
import _thread
from typing import TextIO
#页面代码
root = Tk()
root.title('TPC服务端')
root.geometry('640x480')
label_1 = Label(root,relief=GROOVE,text='从客户端接收的数据')
label_1.place(relx=0.1,rely=0.0,relwidth=0.4,relheight=0.1)
Operate = Text(root,relief=GROOVE)
Operate.place(relx=0.1,rely=0.1,relwidth=0.4,relheight=0.4)
Tips = Text(root,relief=GROOVE)
Tips.place(relx=0.1,rely=0.5,relwidth=0.4,relheight=0.4)
Tips.insert(END,'当前状态:\n')
Tips.configure(state=DISABLED)
root.mainloop()
class TCPServer():
def __init__(self):
self.HOST = '192.0.0.1'
self.PORT = 8080
self.BUFSIZ = 1024
self.ADDRESS = (self.HOST,self.PORT)
self.tcpServerSocket = socket(AF_INET, SOCK_STREAM)
self.tcpServerSocket.bind(self.ADDRESS) #IP地址和固定端口信息
self.tcpServerSocket.listen(5)
def try_connect(self):
global var
var='服务器正在运行,等待客户端连接...\n'
Tips.insert(END,var)
Tips.configure(state=DISABLED)
while True:
var='服务器正在运行,等待客户端连接...\n'
Tips.configure(state=NORMAL)
Tips.insert(END,var)
Tips.configure(state=DISABLED)
self.client_socket, self.client_address = self.tcpServerSocket.accept()
var='客户端{}已连接!\n'.format(self.client_address)
Tips.configure(state=NORMAL)
Tips.insert(END,var)
Tips.configure(state=DISABLED)
while True:
self.data = self.client_socket.recv(self.BUFSIZ)
if(self.data):
var='接收到消息 {}({} bytes) 来自 {}\n'.format(self.data.decode('utf-8'), len(self.data), self.client_address)
# 返回响应数据,接受的数据不做处理即返回
self.client_socket.send(self.data)
var='发送消息 {} 至 {}\n'.format(self.data.decode('utf-8'), self.client_address)
Tips.configure(state=NORMAL)
Tips.insert(END,var)
Tips.configure(state=DISABLED)
Operate.configure(state=NORMAL)
Operate.insert(END,self.data)
Operate.configure(state=DISABLED)
else:
var='客户端 {} 已断开!\n'.format(self.client_address)
Tips.configure(state=NORMAL)
Tips.insert(END,var)
Tips.configure(state=DISABLED)
break
# 关闭socket
self.client_socket.close()
# 取消监听socket,自此拒绝响应其它客户端
self.tcpServerSocket.close()
Server = TCPServer()
_thread.start_new_thread(Server.try_connect)
root.mainloop()
![text](enter image description here
I want to know why such a mistake happened.I am using python to make a simple network communication program.It contains both the client and server sides.This is my client program code.
I am a beginner.
The server connects to the client .i use vscode to write the code.I use python 3.10

Constantly update data from a server and print to a text box

So, I have a server completely written in Python 2.7:
from socket import *
from select import *
HOST = "127.0.0.1"
PORT = 1993
server = socket(AF_INET, SOCK_STREAM)
server.bind((HOST, PORT))
server.listen(5)
clients = []
def getClients():
to_use = []
for client in clients:
to_use.append(client[0])
return to_use
while(True):
read, write, error = select([server],[],[],0)
if(len(read)):
client, address = server.accept()
clients.append([client, address, []])
to_use = getClients()
try:
read, write,error = select(to_use,[],[],0)
if(len(read)):
for client in read:
data = client.recv(1024)
print(bytes.decode(data))
if(data == 0):
for c in clients:
if c[0] == client:
clients.remove(c)
break
else:
for c in clients:
c[2].append(data)
except:
pass
try:
to_use = getClients()
read, write, error = select([], to_use, [], 0)
if(len(write)):
for client in write:
for c in clients:
if c[0] == client:
for data in c[2]:
sent = client.send(data)
if(sent == len(data)):
c[2].remove(data)
break
except:
pass
What I need to do is get constant updates for data (messages) from the
server and print them to a text box made in Tkinter.
The receiving code:
from socket import *
from select import *
HOST = "127.0.0.1"
PORT = 1993
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((HOST, PORT))
while True:
data = bytes.decode(sock.recv(1024))
print data
It doesn't have to be Tkinter, but that's what I have been trying in; as long as it uses a GUI. Don't worry about sending messages I just need to be able to receive the data and print it to the text box/area.
The basic framework is to first create all of the widgets. Next, write a function that reads the data and updates the UI. Finally, arrange to have this function called every few milliseconds.
Roughly speaking, it looks something like this:
import Tkinter as tk
...
class Example(object):
def __init__(self):
self.root = tk.Tk()
self.text = tk.Text(root)
self.text.pack(fill="both", expand=True)
...
def start(self):
self.read_periodically()
self.root.mainloop()
def read_periodically(self):
# read the data
data = bytes.decode(sock.recv(1024))
# update the UI
self.text.insert("end", data)
# cause this function to be called again in 100ms
self.after(100, self.read_periodically)
example = Example()
example.start()
If the data is not a steady stream which causes sock.recv(1024) to block, your UI will freeze while it's waiting for data. If that's the case, you can move the reading of the socket to a thread, and have the thread communicate with the GUI via a thread-safe queue.
If the data is in a steady stream, or you set up a non-blocking socket, you don't have to do any of that.
I wanted to submit a comment first, but give this a try:
You can use something other than a start button to get things going I just put it there for ease of use
from Tkinter import *
import threading
from socket import *
from select import *
master = Tk() #create the GUI window
#put the test program in a seperate thread so it doesn't lock up the GUI
def test_program_thread():
thread = threading.Thread(None, test_program, None, (), {})
thread.start()
def test_program():
HOST = "127.0.0.1"
PORT = 1993
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((HOST, PORT))
while True:
data = bytes.decode(sock.recv(1024))
terminal_listbox.insert(END, str(data))
master.update() #I don't think this line is necessary, but put it here just in case
# set the gui window dimensions and the title on the GUI
master.minsize(width=450, height=450)
master.wm_title("Stack Problem")
# Start button is set to y and starts the test program when hit
start_button = Button(master, text='START', command=test_program_thread)
start_button.place(x=5, y=5)
# scroll bar for the terminal outputs
scrollbar = Scrollbar(master)
scrollbar.place(x=420, y=150)
# Terminal output. Auto scrolls to the bottom but also has the scroll bar incase you want to go back up
terminal_listbox = Listbox(master, width=65, height=13)
terminal_listbox.place(x=5, y=100)
terminal_listbox.see(END)
scrollbar.config(command=terminal_listbox.yview)
#GUI loops here
master.mainloop()

python threading, admin and client

I have been doing some development on this project. achieving multiple connections for the client to the sever. However i am now trying to implement the admin connections through a different port number. Which will not conflict the operation to the client. I changed it so that it calls the function which then calls the operations for which the client or admin which then plays the game or admin controls. how do i call the port number to that function so it runs that code? which calls the game or admin controls? (new to coding) however i feel i need to call them at the bottom of the script....
`# Server
import socket
import math
import random
import re
import threading
#TCP_IP = '127.0.0.1'
#TCP_PORT = 4001
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.bind((TCP_IP, TCP_PORT))
#s.listen(5)
#print("Waiting...")
#connection check
def handle_ClientPort(port): # porting for client through threading
s.bind(("127.0.0.1",port))
s.listen(5)
while True:
(c,a) = s.accept()
t = threading.Thread(target = handle_client, args = (c,a))
t.start()
def handle_AdminPort(port): #proting for adminm connection through threading
s.bind(("127.0.0.1",port))
s.listen(5)
while True:
(c,a) = s.accept()
t = threading.Thread(target = Admin_client, args = (c,a))
t.start()
def handle_Admin(c,a): #function for admin controls
while True:
text = c.recv(80).decode()
if text == 'Who':
c.send("who has workd".encode())
elif text == 'Hello':
c.send('Admin-Greetings'.encode())
else:
c.send('please use the correct admin commands'.encode())
return
def handle_client(c,a): #This works(game)
def within(vaule,goal,n):
if abs(goal - vaule)<= n:
return True
else:
return False
while True:
rmd = random.randrange(0,30)
print('The random number is',rmd) # radom number
hello = c.recv(78).decode()
if hello == "Hello\r\n":
c.send('Greetings\r\n'.encode())
else:
c.send('ERROR\r\n'.encode())
game = c.recv(80).decode()
if game == "Game\r\n":
c.send('Ready\r\n'.encode())
else:
c.send('ERROR\r\n'.encode()) # change this
# hand shake communcation works
while True:
geuss = re.findall('\d+',c.recv(80).decode())
print(geuss)
geuss1 = int(''.join(map(str,geuss)))
print(geuss1)
checker = within(geuss1,rmd,2)
if geuss1 == rmd:
c.send("Correct\r\n".encode())
c.close()
return
elif checker == True:
c.send("Close\r\n".encode())
else:
c.send("Far\r\n".encode())
c.close()
return
admin = 4001
client = 4000
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM,)
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM,)

python socket.error: [Errno 9] Bad file descriptor

I wanted to make a server and a client with Python.
It was supposed to make multiple connections, one, where the server is sending something to the client, and one where the client is sending something to the server.
The first connection worked fine, but the second one crashed with the message:
socket.error: [Errno 9] Bad file descriptor
Here is the Server:
import socket
import errno
import pickle
def Main():
host = '188.174.233.99'
port = 66666
all_text = ['text1', 'text2', 'text3']
all_description = ['Test \n Description1\n', 'Test \n Description1\n', 'Test \n Description1\n']
all_images = ['unlock.png', 'unlock.png', 'unlock.png']
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
s.bind((host, port))
s.listen(1)
while True:
c, addr = s.accept()
c.setblocking(0)
print "Connection from: " + str(addr)
command = c.recv(1024)
if command == 'GIVEALL':
textstring = pickle.dumps([all_text, all_images, all_description])#verwandelt Liste in String
c.send(textstring)
else:
try:
new_event = pickle.loads(command)
print new_event
caption = new_event[0]
image = new_event[1]
describtion = new_event[2]
city = new_event[3]
except:
pass
try:
c.close()
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
except socket.error as e:
if e.errno != errno.ECONNRESET:
raise
pass
if __name__ == '__main__':
Main()
And here is the Client:
import socket
import pickle
from kivy.properties import StringProperty
from kivy.properties import NumericProperty
from kivy.properties import ListProperty
class Netclient(object):
def __init__(self):
self.s = socket.socket()
self.texte = []
self.current = 'All'
self.ip = '188.174.233.99'
self.port = 66666
def giveWid(self):
print 'give Widgets executed'
if self.current == 'All':
self.texte, self.images, self.description = self.sentHOT(self.ip, self.port)
return self.texte, self.images, self.description
def sentHOT(self, host, port):
self.s.connect((host, port))
self.s.send('GIVEALL')#sends command
recived_string = self.s.recv(1023)
more_text = pickle.loads(recived_string)#verwandelt string in liste
self.s.close()
print 'closed'
return more_text[0], more_text[1], more_text[2]
def add_event(self, caption, image, description, city='Pawonkow'):
new_event = [caption, image, description, city]
new_compact_event = pickle.dumps(new_event)
self.s.connect((self.ip, self.port))
self.s.send(new_compact_event)
self.s.close()
n = Netclient()
t, i, d = n.giveWid()
print t
n.add_event('new', 'new.png', 'ew event', 'Hanau')
The reason is that you are trying to reconnect a closed socket. You have to either create a new socket or reuse the old one as long as it's connected.
In method def sentHOT(...): comment the line self.s.close() and in method def add_event(...) comment the line self.s.connect((self.ip, self.port)) then should work. Further, please take a look at this tutorial, it helps you with socket programming.

Categories

Resources