I'm currently working on a simple Python script that connects to an IP/Port and lets you preform commands. Kinda like telnet. I want it to connect to lets say MySQL(Just an example) and execute MySQL commands like you would with Telnet or NetCat.
But lets say I connect to a service, I can't execute commands. I'm trying to connect to a custom port on localhost. Let me show the code:
try:
sock.connect((host, port))
recvdata = sock.recv(socksize)
print("Type your commands now")
while(1): #Setting a loop
print(recvdata)
userInput = raw_input(">")
sock.send(userInput + '\r\n\r\n')
print(recvdata)
except KeyboardInterrupt:
print("\nConnection closed")
sys.exit()
So this is what I get when I connect:
:: !Test service! ::
If I type anything, I just get the banner again. The same banner over and over no matter what.
Your recvdata = sock.recv(socksize) is outside of the recv loop. I think, a good introduction to socket programming in Python might be helpful to you. Your previous question and this one would have been easily spotted by you using that introduction tutorial. Have a look at an example socket echo server/client (at this site), which you can modify further and proceed with your task. Run two separate terminals, run the echo server at one end and use the echo client with address pointint to 127.0.0.1.
Well, no wonder. You never actually call sock.recv on the communicating socket after you send your input.
Prior to the loop, recvdata contains the "banner" from the initial connect. But once you're in the loop, this variable is never changed.
I believe what you want is:
sock.connect((host, port))
recvdata = sock.recv(socksize)
print(recvdata)
print("Type your commands now")
while(1): #Setting a loop
userInput = raw_input(">")
sock.send(userInput + '\r\n\r\n')
recvdata = sock.recv(socksize)
print(recvdata)
Related
i wrote a script in python for serial communication between my M5Stack Stick C (like raduino) and the raspberry pi.
all work fine. i can send "X","Y" or "Z" from raspberry py to the stick and he will reply the value (G-Force) back to the raspi! so far so good
Codes:
Python on raspy:
import serial
import time
import threading
ser = serial.Serial('/dev/rfcomm5') #init serial port
input_line = []#init input char array
def process_data(_data):
#called every time a sream is terminated by \n
#and the command string is ready to use
command = convert(_data)
print(command)
def convert(s): #convert the char list in a string
new = "" #init string to append all chars from char array
for x in s: # traverse in the string
new += str(x)
return new # return string
def processIncomingByte(inByte):#adding incoming chars to input_line
global input_line# globalize the input_line
if(inByte == '\n'):#if \n is incoming, end the chararray and release process data method
process_data(input_line)
input_line = []#reset input_line for next incoming string
elif(inByte == '\r'):
pass
else:#put all incoming chars in input_line
input_line.append(inByte)
while True:
while(ser.in_waiting > 0):#while some data is waiting to read....
processIncomingByte(ser.read())#.... process bytes whit method
ser.write(b'X\n')
time.sleep(0.5)
before the script work, i have to manually bind the m5Stak Stick-C over Blueman
to /dev/Rfcomm5. it work just fine over GUI or Console....
but now i would like to connect the stick via python to rfcomm5 (just by know the MAC adress, will be found in a config file later on...)
i startet to investigate a bit, but the more i research the more confused i am!!
i read some stuff over sockets and server-client aproaches. over a seperated script and so on....
i tested this code:
from bluetooth import *
target_name = "M5-Stick-C"
target_address = None
nearby_devices = discover_devices()
for address in nearby_devices:
if (target_name == lookup_name( address )):
target_address = address
break
if (target_address is not None):
print ("found target bluetooth device with address ", target_address)
else:
print ("could not find target bluetooth device nearby")
and indeed it found the device (just testing)!
but do i realy need to make a second script/process to connect to from my script?
is the the M5stack Stick-C the server? (i think so)
im so confused about all that stuff. i coded a lot, but never whit sockets, server-client stuff.
basically the communication (server/client?) works.
i just need to connect the device i found in the second script via macadress to rfcomm5 (or whatever rfcomm).
do i need a bluetooth socket? like in this example
https://gist.github.com/kevindoran/5428612
isnt the rfcomm the socket or am i wrong?
There are a number of layers that are used in the communication process and depending where you tap into that stack will depend what coding you need to do. The other complication is that BlueZ (the Bluetooth stack on linux) changed how it works over recent times leaving a lot of out of date information on the internet and easy for people to get confused.
With two Bluetooth devices, they need to establish a pairng. This is typically a one off provisioning step. This can be done with tools like Blueman or on the command line with bluetoothctl. Once you have a pairing established between your RPi and the M5Stack Stick, you shouldn't need to discover nearby devices again. Your script should just be able to connect if you tell it which device to connect to.
The M5Stack stick is advertising as having a Serial Port Profile (SPP). This is a layer on top of rfcomm.
There is a blog post about how this type of connection can be done with the standard Python3 installation: http://blog.kevindoran.co/bluetooth-programming-with-python-3/
My expectation is that you will only have to do the client.py on your RPi as the M5Stack Stick is the server. You will need to know its address and which port to connect on. Might be some trial and error on the port number (1 and 3 seem to be common).
Another library that I find helpful for SPP, is bluedot as it abstracts away some of the boilerplate code: https://bluedot.readthedocs.io/en/latest/btcommapi.html#bluetoothclient
So in summary, my recommendation is to use the standard Python Socket library or Bluedot. This will allow you to specify the address of the device you wish to connect to in your code and the underlying libraries will take care of making the connection and setting up the serial port (as long as you have already paired the two devices).
Example of what the above might look like with Bluedot
from bluedot.btcomm import BluetoothClient
from signal import pause
from time import sleep
# Callback to handle data
def data_received(data):
print(data)
sleep(0.5)
c.send("X\n")
# Make connection and establish serial connection
c = BluetoothClient("M5-Stick-C", data_received)
# Send initial requests
c.send("X\n")
# Cause the process to sleep until data received
pause()
Example using the Python socket library:
import socket
from time import sleep
# Device specific information
m5stick_addr = 'xx:xx:xx:xx:xx:xx'
port = 5 # This needs to match M5Stick setting
# Establish connection and setup serial communication
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.connect((m5stick_addr, port))
# Send and receive data
while True:
s.sendall(b'X\n')
data = s.recv(1024)
print(data)
sleep(0.5)
s.close()
I have created a chat bot for Twitch IRC, I can connect and create commands etc etc, however I cannot use keyboard-interrupt in the command prompt. I suspect it is because it's stuck in this infinite loop, and I don't know how to fix this? I am new to programming btw!
Here is the code I have in my Run.py, openSocket() is defined in another file, basically connection to the server. s = socket.socket.
First part in the while-loop basically just reads the server messages, I think it's pretty straight forward for you guys!
s = openSocket()
joinRoom(s)
readbuffer = ""
while True:
readbuffer = readbuffer + s.recv(1024).decode("utf-8")
temp = str.split(readbuffer, "\n")
readbuffer = temp.pop()
for line in temp:
if "PING" in line:
s.send("PONG :tmi.twitch.tv\r\n".encode("utf-8"))
print("---SENT PONG---")
printMessage(getUser, getMessage, line)
message = getMessage(line)
for key in commands:
command = key
if command in message:
sendMessage(s, commands[command])
((Edit: I also have this problem where the connection to the server seems to time out for whatever reason. I managed to get it keep connection with ping/pong for about 40-45min, but then it disconnected again.
EDIT:
Sorry the original post was super messy. I have created this pastebin with the least amount of code I could use to recreate the problem.
If the IRC chat is inactive it will disconnect, and I can't get it to send 2 pings in a row without any messages in between, not sure if that's because it disconnects before the 2nd ping or because of the 2nd ping.
On at least one occasion it has disconnected even before I got the first ping from the server.
Pastebin: pastebin.com/sXUW50sS
Part of code that you posted doesn't have much to do with problem you described.
This is a guess (although an educated one). In you socket connection you are probably using try: except: and using Pokemon approach (gotta catch 'em all)
Thing here would be to find a line where you are doing something like this:
except:
pass
and change it to:
except (KeyboardInterrupt, SystemExit):
raise
except:
pass
Obviously I'm not trying to say here that your porgram should catch all exceptions and just pass like if nothing happened. Main point is that you are probably already doing that (for i-have-no-idea-why reasons) and you should have special treatment for system errors.
I plan to make a "telnet bot".
There is a game which has a telnet server built ingame, that you can turn on. Now, this telnet server logs all of the activity in the console (kills, players joining, chat, etc) and you can also type stuff into putty and it will be received ingame.
Anyway, I tried to use Python Telnetlib, but there doesn't seem to be any function that reads the last line. I also tried using sockets, but I don't quite understand the Telnet protocol.
Is there a way to use telnetlib or sockets to do the following thing?:
#def readAndDo():
serverOutput = telnet.readLastLine() #doesn't exist, this would be like the thing I need
if "> AuthorizeMe" in serverOutput.splitlines()[:-1]:
nickname = serverOutput[2:-13]
tn.write(b"playerReq = playergetByName(\"" + nickname + "\")\n")
tn.write(b"playerReq = playerInfo(\"playerReq\")\n")
username = telnet.readLastLine()
print username
readAndDo()
if "Victim" in serverOutput:
print serverOutput
readAndDo()
else:
sleep(1)
print serverOutput
readAndDo()
readAndDo()
You don't want to read the last line in telnet, but want to react on situations, where the telnet server wants input. There is no other way to parse the whole messages, the server sends and answer when the server expects answers.
Okay, so in some experimentation with sockets and networking, I've set up a very basic chat client/server that runs on Unix flawlessly. Now I'm hitting some errors in the translation to win32. In preface, I understand that select.select() on Windows won't accept socket objects and have (I think) compensated coherently by not passing it the socket object, but the socket number. However, the script still hangs on the select.select() function and I have no idea why. The script only hangs until the server receives a message, after which it allows the client to send messages, however the client can't receive messages from the server, no matter what. I'm trying to troubleshoot these two bugs as best as I can, but my research has turned up dry. Here's the problem code, thanks in advance.
while True:
socket_list.append(s)
read_sockets, write_sockets, error_sockets = select.select(socket_list, [], [], 20)
if not (read_sockets or write_sockets or error_sockets):
if afk == False:
s.send('[Status]: '+str(_user)+' has gone afk.\n')
sys.stdout.write('\n[+]: You have gone afk.\n')
afk = True
prompt()
for sock in read_sockets:
print ('Starting for sock in read_sockets') #DEBUG#
if sock == s:
print ('Getting here.') #DEBUG#
data = sock.recv(4096)
if not data:
sys.stdout.write('[!]: Disconnected from chat server by server.\n'+W)
choice = raw_input('[*]: Press Enter to continue.')
_logic()
else:
sys.stdout.write(data)
else:
# Rest of the Program (Runs correctly) #
It sounds like you forgot to set the sockets non-blocking. Like pretty much all status reporting functions, select does not make future guarantees. You also need to handle the case where read returns a "would block" indication. You can't rely on select to predict the results of future read operations.
I've been looking around all day, but I haven't been able to fix the problem I've got with my chat client here.
Here's the issue: I recently decided to change the client so that it would allow the user to input any message they wanted without having to wait for a reply first (blocking or something stops my program until a reply is in)
I decided to use the select.select module to do so, but after writing a couple different versions of my client today trying to get it to work, I keep getting stuck at this one point.
Whenever I enter a message, the loop gets stuck somewhere, (probably at .recv data)
how can I fix this? Nothing I try gets it to go by that.
Edit: To be more clear, when I run, I get to the point where I input the message, hit enter and then nothing happens at all. It just stays running like that.
from socket import *
import select
import sys #because why not?
print("New Chat Client Using Select Module")
HOST = input("Host: ")
PORT = int(input("Port: "))
s = socket(AF_INET,SOCK_STREAM)
print("Trying to connect....")
s.connect((HOST,PORT))
s.setblocking(0)
# Not including setblocking(0) because select handles that.
print("You just connected to",HOST,)
# Lets now try to handle the client a different way!
while True:
Incoming_data = [s]
Exportable_data = []
Exceptions = []
User_input = input("Your message: ")
rlist,wlist,xlist = select.select(Incoming_data,Exportable_data,Exceptions)
if User_input == True:
Exportable_data += [User_input]
for i in rlist:
data = i.recv(1024)
if data == "":
continue
for i in wlist:
if Exportable_data is True:
i.send(Exportable_data)
continue
Is there any way I can override the blocking (that I presume is the problem) when it's set to receive data? Won't s.setblocking(0) make it so it won't block(?) (With or without it still gets stuck)
Thanks for taking a look
I think you should have separate thread or process which will interact with your socket and another thread, which will accept user input and print chat messages. Interaction between the threads you can do using 2 queues: for incoming and outgoing messages.
Have a look at threading and queue modules.