With my program, I am attempting to connect to a IP address using socket.socket(), and when it connects to capture a bit of morse code, decode it, and then push the answer back through the socket with socket.sendall(). I have it so I can connect to the IP address, decode the message, and even send back my answer, but when I send back the answer it says that it's wrong, even though I know for a fact it isn't. I'm wondering if maybe, when I'm sending back my answer, if I'm sending back an additional set of quotation marks around it or something? Any help would be appreciated.
import socket
def morse(code):
decoded = []
CODE = [['.-', 'A'],['-...', 'B'],['-.-.', 'C'],['-..', 'D'],['.', 'E'],['..-.', 'F'],['--.', 'G'],['....', 'H'],['..', 'I'],['.---', 'J'],['-.-', 'K'],['.-..', 'L'],['--', 'M'],['-.', 'N'],['---', 'O'],['.--.', 'P'],['--.-', 'Q'],['.-.', 'R'],['...', 'S'],['-', 'T'],['..-', 'U'],['...-', 'V'],['.--', 'W'],['-..-', 'X'],['-.--', 'Y'],['--..', 'A']]
for i in CODE:
if i[0] == code:
decoded.append(i[1].lower())
if code == '':
decoded.append('.')
return decoded
def netcat(hostname, port, content):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, port))
while 1:
data = s.recv(1024)
if data == "":
break
if "text:" in repr(data):
s.sendall(content)
print("Received:", repr(data))
if "-" in repr(data):
splitMorse = repr(data).split(' ')
splitMorse = splitMorse[8:len(splitMorse)-2]
decoded = []
for i in splitMorse:
decoded.extend(morse(i))
strDecoded = ''.join(decoded)
strDecoded = strDecoded.replace("....................................................", " ")
print("{}\n".format(strDecoded))
#HERE IS WHERE I AM SENDING THE STRING BACK
print(s.sendall("{}\n".format(strDecoded)))
print("Connection closed.")
s.shutdown(socket.SHUT_WR)
s.close()
content = "GET\n"
netcat('146.148.102.236', 24069, content)
At the end of sending my string through the socket, I added an "\n" because otherwise it won't accept my string and it'll sit there forever (because you have to press enter after typing. Here is my output:
('Received:', "'------------------------------------------\\nWelcome to
The Neverending Crypto!\\nQuick, find Falkor and get through this!\\nThis
is level 1, the Bookstore\\nRound 1. Give me some text:'")
None
('Received:', "'GET encrypted is --. . - \\nWhat is ..-. .-. .- --. -- .
-. - .- - .. --- -. decrypted?\\n:'")
fragmentation
None
('Received:', "'No... I am leaving.\\n'")
Connection closed.
I think your logic is flawed. The first message contains text: and it also contains -. I think you want elif for your final if.
For your sequence of if statements in netcat(), try this:
if data == "":
break
print("Received:", repr(data))
if "text:" in repr(data):
...
elif "-" in repr(data):
...
Related
Posting this here out of desperation. Any help is appreciated. Thank you.
Backstory:
I am helping my friend with a device that he got from China. The device supposedly sends a audio file to my server using UDP.
assuming you want some Python code to do this automatically, here's how I'd validate and decode the packet:
import struct
def decode_packet(packet):
framehead, version, command, datalen = struct.unpack_from('!HBBH', packet)
valid = (
framehead == 0x55aa and
version == 0x00 and
command == 0x1e and
len(packet) <= datalen + 11
)
if not valid:
# ignore other protocols using this address/port
print(
' header invalid',
f'{framehead:04x} {version:02x} {command:02x} {datalen:04x}'
)
return
if len(packet) < datalen + 11:
print(' warning: packet was truncated')
offset, = struct.unpack_from('!I', packet, 6)
if datalen == 4:
print(f' end of data: file size={offset}')
return
data = packet[10:10+datalen]
print(f' got data: offset={offset} len={len(data)} hex(data)={data.hex()}')
if len(packet) == datalen + 11:
print(f' hex(checksum)={packet[datalen + 10:].hex()}')
it obviously prints out a lot of stuff, but this is good to seeing if the device is actually following the documented protocol. it doesn't seem to be, as the +4 on the data length doesn't seem to be being applied. you can test this with:
decode_packet(bytes.fromhex('55aa001e038400000000a9b6ad98d2923...'))
assuming you can get this to function correctly, you can put this into some code that listens for packets on the correct port:
import socket
def server(portnum):
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.bind(('', portnum))
while True:
packet, addr = sock.recvfrom(10240)
print(f'received {len(packet)} bytes from {addr[0]}')
decode_packet(packet)
again, doesn't do much. you'd want to write the data to a file rather than printing it out, but you can pull the offset out and you get a signal for when the data has finished transferring
Hello so i have my server with a database (dictironay) and another passworddatabase
import socket
import sys
from _thread import *
host = ""
port = 8000
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket Created")
try:
serversocket.bind((host, port))
except socket.error as e:
print(str(e))
sys.exit()
database = {"name1" :{"hair" : "red", "size" : 1.50}}
password_database = {"name1": "1234",
"name2": "4321"}
def client_thread(conn): #threader client
welcome = "Welcome to the server. Type something and hit enter \n"
conn.send(welcome.encode("UTF-8"))
login(conn)
while True: # NOT IMPORTANT KEEP READING
data = conn.recv(24)
reply = data.decode("UTF-8")
if reply == "1":
menu1 = "Menu 1: Buy \n"
conn.send(menu1.encode("UTF-8"))
else:
wrong = "wrong option \n"
conn.send(wrong.encode("UTF-8"))
def login(conn): #MY LOGIC PROBLEM IS HERE
log = "Log in MENU: \n"
logi = log.encode("UTF-8")
conn.send(logi)
us = "Username: \n"
use = us.encode("UTF-8")
conn.send(use)
userr = conn.recv(24)
user = userr.decode("UTF-8")
pa = "Password: \n"
pasw = pa.encode("UTF-8")
conn.send(pasw)
passr = conn.recv(24)
passw = passr.decode("UTF-8")
tries = 0
while tries < 3:
if user in passwordDictionary and passwordDictionary[user] == passw:
print("Logged in")
menu()
else:
print("Wrong Username Or Password \n")
tries += 1
print("You failed the login too many times, blocking you out")
conn.close()
while 1: # NOT IMPORTANT
conn, addr = serversocket.accept()
print("Connected with " + addr[0] + ":" + str(addr[1]))
start_new_thread(client_thread, (conn, ))
serversocket.close()
Whats working:
The server is working fine, i'm having troubles doing the login on the client side.
client.py ==> client DOESNT go into the if data == Log in menu
is there a better way to do this?
#! /usr/bin/python3
import socket
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('localhost', 8000))
print("Connected")
datae = clientsocket.recv(24)
data = datae.decode("UTF-8")
clientsocket.send(datae)
while data != "!q":
if data == "Log in MENU: \n":
usere = input()
user = usere.encode("UTF-8")
clientsocket.send(user)
What would be the best way to create an log in interaction with the server?
the server has the usernames and passwords, i need to log in and then i need to edit the database depending on what user was chossen, but i'm having a hard time doing the algorithm
theres problems with the code you provided... however ill assume it actually works for you somehow and rather than copy paste you manually typed it
you are recieveing the first message here
datae = clientsocket.recv(24)
data = datae.decode("UTF-8") # GOT A MESSAGE
You then have the message datae = b'Welcome to the server. '
which does not match "Log in MENU: \n", and data != "!q" so it goes back into your loop and checks if data == "Log in MENU: \n" it doesnt so it repeats ... but you never get the next message instead try something like this second message
data = ""
while data != "!q":
if data == "Log in MENU: \n":
usere = input()
user = usere.encode("UTF-8")
clientsocket.send(user)
data = clientsocket.recv(24).decode("UTF-8") # GET THE NEXT MESSAGE!
but even then you are going to have problems because your server continues to write so you will get something like "Log in MENU: \nUsername" or something .... basically you need to work out a better message passing scheme than recv(24)
To avoid Errors try using a header with something like 64 Bytes wich always is the first message send. This Header is then used to send the actual length of the following message to the server. For example:
def send_response(conn, msg):
message = msg.encode(FORMAT)
send_length = len(str(len(message)).encode(FORMAT))
res_len = bytes(len(message)) + (b' ' * (HEADER - send_length))
print(f"[SENDING MESSAGE] {msg}")
conn.send(res_len)
conn.send(response)
I'm getting 'TypeError: coercing to Unicode: need string or buffer, tuple found' when trying to send data back to server.
Here is my code:
def send_and_receive_udp(address, port, id_token):
# Create UDP socket
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Contents of message
message = 'Hello from %s\r\n' %id_token
ack = True
eom = False
dataRemaining = 0
length = len(message)
data = struct.pack('!8s??HH64s', id_token, ack, eom, dataRemaining, length, message)
# Send given message to given address and port using the socket
udp_socket.sendto(data, (address, port))
while(True):
# Send given message to given address and port using the socket
# Receive data from socket
data_recv, address = udp_socket.recvfrom(1024)
id_token, ack, eom, dataRemaining, length, message = struct.unpack('!8s??HH64s', data_recv)
print message
# Last EOM is True, otherwise False
if(eom == True):
# Break loop
print 'Lopetetaan'
break
words = []
chars = []
# Append list from message one character at time
for i in range(length):
chars.append(message[i])
# Join words back to one string
word = ''.join(chars)
# Make a array where every word is one member of array
words = word.split(' ')
words.reverse()
# Make a new string from array
send_data = ' '.join(words)+'\r\n'
data = struct.pack('!8s??HH64s', id_token, ack, eom, dataRemaining, length, send_data)
udp_socket.sendto(data, (address, port))
# close the socket
udp_socket.close()
return
This program is supposed to send UDP-message to server, then get list of words as response and then this should send the list in reversed order back to server. This is supposed to go as long as EOM is True.
First udp_socket.sendto(data, (address, port)) works just as I want. The last one creates this TypeError and I have no idea why.
You are overwriting address in
data_recv, address = udp_socket.recvfrom(1024)
so that it is a tuple. Use
data_recv, (address, port) = udp_socket.recvfrom(1024)
I've Looked At Other Answered Questions and The Only Solution I've Found Is That It needs to send it encoded. But I still receive this error whether or not this is encoded. Any ideas??? The commented lines are ones that I removed to make it function as intended. I'm new to this so hopefully this question made sense.(I'm Using Version 3.6)
Host = servershost
Port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((Host, Port))
s.setblocking(0)
rT = threading.Thread(target=receiving, args=("RecvThread", s))
rT.start()
message = input(Username + ": ")
#s.sendto(message)
while message != 'q':
if message != '':
s.sendto(Username + message.encode('utf-8'), server)
#tlock.aquire()
message = input(Username + ': ')
tlock.release()
time.sleep(0.2)
shutdown = True
rT.Join()
s.close()
socket object needs a bytes (binary) object, not a string (at least in Python 3).
So, just encode both strings so the result is a bytes object:
s.sendto((Username + message).encode('utf-8'), server)
i have the following code:
import socket # Import socket module
import sys
s = socket.socket() # Create a socket object
host = '' # Get local machine name
port = 1234 # Reserve a port for your service.
s.connect((host, port))
while 1:
data = s.recv(1024)
print ' data ' , data
d = data.split('?') # parsing values from server
if len(d) < 2:
# if does not contain ?, do nothing
continue
else:
a = d[0]
b = d[1].replace('\n', '')
# check how a compares to b, and send response accordingly
if (a > b):
s.send('1')
elif (a == b):
s.send('2')
else:
s.send('3')
s.close() # Close the socket when done
Without the processing code I have, it works fine if I just send a random value. But with the code above, I can only parse the first set of line, and then it stops. (I assume it closes the socket or something?)
The data coming from the socket looks like '1 ? 23' or '23 ? 1' , etc. it expects a response that determines how the two numbers relate.
In comparison, if I have this code:
import socket # Import socket module
import sys
s = socket.socket() # Create a socket object
host = '' # Get local machine name
port = 1234 # Reserve a port for your service.
s.connect((host, port))
backlog = ''
while 1:
data = s.recv(1024)
sp = data.split('\n')
if len(sp) < 2:
backlog += data
continue
line = backlog + sp[0]
backlog = sp[1]
data = line
print ' data ' , data
if not data:
break
s.send ('2')
s.close() # Close the socket when done
This code will yield a server response of either 'Correct!' or 'Incorrect...try again!' depending on whether it's right or wrong.
You seem to assume that you always get a full line with each read() call. That is wrong.
You should split your input into lines, and only if you have a full line, you proceed.
backlog = ''
while 1:
data = s.recv(1024)
# do we have a line break?
sp = data.split('\n')
if len(sp) < 2:
# no, we haven't...
backlog += data
continue
# yes, we have.
line = backlog + sp[0] # first part is the now complete line.
backlog = sp[1] # 2nd part is the start of the new line.
print ' line ' , line
d = line.split('?') # parsing values from server
if len(d) < 2:
# if does not contain ?, do nothing
continue
else:
a = int(d[0]) # we want to compare numbers, not strings.
b = int(d[1])
# check how a compares to b, and send response accordingly
if (a > b):
s.send('1')
elif (a == b):
s.send('2')
else:
s.send('3')
Try out what happens now.
Another question which occurs to me is what exactly does the server expect? Really only one byte? Or rather '1\n', '2\n', '3\n'?